neosmart pevents的功能是模拟Win32 Event API,方便移植。
打开WFMO宏定义以后,调用WaitForMultipleEvents,能走到函数RemoveExpiredWaitHelper。
我向作者报告了错误,作者认为调用方法不正确。
我把测试代码发给作者,作者无回应。
微软的一个开源项目WinObjC,借用了pevents的代码,并且做了改动。是否能够稳定运行,不清楚,或许只是想当作临时代码。
bool RemoveExpiredWaitHelper(neosmart_wfmo_info_t_ wait)
{
int result = pthread_mutex_trylock(&wait.Waiter->Mutex); /* 返回值 result 为 0, Mutex 为锁定状态. */
if (result == EBUSY)
{
return false;
}
assert(result == 0);
if (wait.Waiter->StillWaiting == false)
{
--wait.Waiter->RefCount;
assert(wait.Waiter->RefCount >= 0);
if (wait.Waiter->RefCount == 0)
{
wait.Waiter->Destroy(); /* Waiter 的成员 Mutex 在锁定状态时候,无法销毁的,这会导致泄漏。 */
delete wait.Waiter;
}
else
{
result = pthread_mutex_unlock(&wait.Waiter->Mutex);
assert(result == 0);
}
return true;
}
result = pthread_mutex_unlock(&wait.Waiter->Mutex);
assert(result == 0);
return false;
}
下面是测试代码
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <string.h>
#define WFMO
#define PULSE
#include "pevents.cpp"
const int EVENTS_COUNT = 10;
const int THREADS_COUNT = 10;
static
neosmart::neosmart_event_t sg_events[EVENTS_COUNT];
static
void * thread_proc( void * param )
{
int i = 0;
int index = 0;
int status = 0;
for (i = 0; true; ++i )
{
index = 0;
status = neosmart::WaitForMultipleEvents( sg_events, EVENTS_COUNT, false, 1, index );
if (0 != status)
{
// printf( "[%4d]WaitForMultipleEvents status = %s \n", i, strerror(status) );
}
}
return NULL;
}
static
pthread_t sg_hthread[THREADS_COUNT];
static void set_events_proc( void )
{
int i;
for(;;)
{
// usleep( 1 * 1000 );
for (i = 0; i < EVENTS_COUNT; ++i )
{
neosmart::SetEvent( sg_events[i] );
}
}
}
int main( void )
{
int i = 0;
int status = 0;
for( i = 0; i < EVENTS_COUNT; ++i )
{
sg_events[i] = neosmart::CreateEvent( false, false );
}
for (i = 0; i < THREADS_COUNT; ++i )
{
status = pthread_create( &sg_hthread[i], NULL, thread_proc, NULL );
if (0 != status)
{
printf( "pthread_create failed status = %d \n", status );
goto LABEL_THREAD_FAIL;
}
}
set_events_proc();
for (i = 0; i < THREADS_COUNT; ++i )
{
status = pthread_join( sg_hthread[i], NULL );
if (0 != status)
{
printf( "pthread_join failed status = %d \n", status );
}
}
LABEL_THREAD_FAIL:;
for (i = 0; i < EVENTS_COUNT; ++i )
{
neosmart::DestroyEvent( sg_events[i] );
sg_events[i] = NULL;
}
return 0;
}