2010-02-06 2 views
1

Следующий код работает отлично на моем XP SP2 машине, но вызов WaitForSingleObject ждет неопределенное время, когда работает на моей машине перспективы:WaitForSingleObject получает свой семафор в XP, но не в Vista,

HANDLE ghSemaphore; 
ghSemaphore = CreateSemaphore(NULL, 0, 1, "COM_PHILOERTEL_FINA"); 
if (ghSemaphore == NULL) { 
MessageBoxA(NULL,"Error creating semaphore","ERROR",0); 
return FALSE; 
} 

MessageBoxA(NULL,"Semaphore created. Waiting for it to be triggered","ERROR",0); 
WaitForSingleObject(ghSemaphore, INFINITE); 
// got the semaphore, ready to rock 

MessageBoxA(NULL,"Got the semaphore, ready to rock!","Notice",0); 

Вот нить, релизы семафора:

ghSemaphore = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "COM_PHILOERTEL_FINA"); 
if (ghSemaphore == NULL) { 
    MessageBoxA(NULL,"Failed to open semaphore","ERROR",0); 
    return FALSE; 
} 

if (0 == ReleaseSemaphore(ghSemaphore, 1, NULL)) { 
    MessageBoxA(NULL,"Plugin was unable to release the semaphore","ERROR",0); 
    return FALSE; 
} 

Названный семафор был недавним дополнением, которое не принесло пользы. До этого потоки просто делили ghSemaphore с его анонимным семафором. Нет очевидной разницы. Кто-нибудь знает, почему этот бинарный файл (скомпилированный на машине XP в VC6, Express Edition fwiw) не будет работать в Vista? Как я сказал выше, вызов WaitForSingleObject - это то, что никогда не заканчивается.

Чин!

+1

MSDN говорит, что ReleaseSemaphore() требует SEMAPHORE_MODIFY_STATE атрибут безопасности. Вы используете NULL в качестве параметра атрибута безопасности в CreateSemaphore(). Можете ли вы попробовать один раз с этим набором атрибутов безопасности? – Naveen

+0

@Naveen, как только «OpenSemaphore» преуспеет (и, по-видимому, делает это, поскольку OP, вероятно, замечает обратное), у дескриптора * есть * право доступа SEMAPHORE_MODIFY_STATE. – avakar

+0

@philo, код отлично работает для меня в Vista, даже когда я помещаю фрагменты в отдельные процессы. Есть ли что-то особенное в вашем процессе или это нормальное неэлектированное приложение? – avakar

ответ

0

я не могу проверить это прямо сейчас, но слышал об этом, так что попробуйте: Изменить первый аргумент CreateSemaphore от NULL пустого экземпляра SECURITY_ATTRIBUTES

SECURITY_ATTRIBUTES dumy; 
dumy.nLength = sizeof(dumy); 
dumy.lpSecurityDescriptor = 0; 
dumy.bInheritHandle = TRUE; 
CreateSemaphore(&dumy, 0, 1, "COM_PHILOERTEL_FINA"); 

Кстати именем семафора с lMaximumCount = 1 полностью эквивалент названного мьютекса. Поэтому рассмотрите возможность использования мьютекса.

+0

Вау, спасибо за быстрый ответ! Однако такое же поведение с этим кодом добавлено. – philo

+0

Похоже, что @Naveen прав, для вызова ReleaseSemaphore требуется только SEMAPHORE_MODIFY_STATE. – Dewfy

0

Решено. Это была полная ошибка пользователя. Спасибо @Dewfy, @Naveen и @avakar за ваши продуманные ответы.

Я был уверен, что пользовательская функция вызывается, потому что я показываю ее результат в макете Filemaker. Я не понял, что эти возвращаемые значения кэшируются по умолчанию. Функция никогда не вызывалась. Ваши предложения были действительно полезны, потому что только когда я полностью понял, что делаю с моими потоками и семафорами, я смог отступить и сказать «зависать, что-то не так».

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

чувствует себя хорошо