Общие настройки между пользователями и процессами

У меня есть два процесса - пользовательский процесс и LaunchDaemon корневого уровня. Я бы хотел, чтобы оба процесса имели общие настройки. Я пытался заставить это работать через базу данных sqlite, но столкнулся с проблемами повреждения. Я думал об использовании NSUserDefaults, но NSGlobalDomain кажется глобальным только для пользователя, и мне нужен постоянный домен для нескольких пользователей, который NSUserDefaults, похоже, не предоставляет.

Я пробовал читать и писать файл XML напрямую, и я могу заставить его работать нормально с несколькими потоками (через простой NSLock), но когда я пытаюсь применить O_EXLOCK к файлу, чтобы предотвратить запись в файл одного процесса в то время как другой, похоже, не работает.

У CFPreferences почти те же проблемы, что и у NSUserDefaults. Существует константа kCFPreferencesAnyUser, но в документации сказано, что я могу использовать ее, только если у меня есть права администратора (которых нет у пользовательского процесса).

Итак, мой вопрос заключается в следующем:

Как я могу эффективно реализовать общие настройки между процессами и пользователями?


person Dave DeLong    schedule 26.08.2009    source источник


Ответы (2)


Лучше всего, вероятно, подойдет подход O_EXLOCK, для удобства заключенный в NSFileHandle (-initWithFileDescriptor:). Что-то вроде этого (не проверено, не скомпилировано):

Пишу:

int fd = open([path UTF8String], O_TRUNC|O_EXLOCK);
if (fd >= 0)
{
    NSFileHandle *fh = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];
    [fh writeData:xmlData]; // Creating xmlData left as exercise for the reader
    [fh release];
}
else // Error stuff

Чтение:

int fd = open([path UTF8String], O_RDONLY|O_SHLOCK);
if (fd >= 0)
{
    NSFileHandle *fh = [[NSFileHandle alloc] initWithFileDescriptor:fd closeOnDealloc:YES];
    NSData *xmlData = [fh readDataToEndOfFile];
    [fh release];
}
else // Error stuff

Конечно, они будут блокироваться, поэтому вам нужно использовать O_NONBLOCK или поместить их в поток, не связанный с пользовательским интерфейсом, чтобы ваше приложение с графическим интерфейсом не попало в пляжный мяч.

В чем проблема, которую вы видите с O_EXLOCK?

person Rob Napier    schedule 26.08.2009

Обратите внимание, что использование O_EXLOCK и O_SHLOCK с _3O_SHLOCK4_ просто позволяет избежать вызова _5O_SHLOCK6_. Mac OS X поддерживает только рекомендательную блокировку, и, как отмечает справочная страница для flock():

Рекомендательные блокировки позволяют взаимодействующим процессам выполнять согласованные операции с файлами, но не гарантируют согласованности (т. е. процессы могут по-прежнему обращаться к файлам без использования консультативных блокировок, что может привести к несогласованности).

Таким образом, вы столкнетесь с проблемами, если оба приложения не выбирают систему рекомендательной блокировки каждый раз, когда они открывают файл с рекомендательной блокировкой.

Вы также можете попробовать, чтобы пользовательский процесс выполнял вызовы по умолчанию через демон с использованием RPC. Затем он будет обрабатывать все записи по умолчанию от имени клиентских приложений; чтение по умолчанию уже будет касаться любого пользователя, текущего хоста/любого хоста по умолчанию.

person Jeremy W. Sherman    schedule 03.09.2009