#ifdef WIN32 // this is a linux version of the following functions, // nothing to do for windows. // CreateSemaphore, CloseHandle, ReleaseSemaphore, WaitForSingleObject, CreateThread #else // not WIN32 #include "wintypes.h" #include #include #include #include #include typedef struct { pthread_mutex_t mutex; pthread_cond_t condition; int semCount; }sem_private_struct, *sem_private; HANDLE CreateSemaphore( LPSECURITY_ATTRIBUTES, LONG lInitialCount, LONG lMaximumCount, LPCSTR lpName ) { sem_private token; token = (sem_private) malloc(sizeof(sem_private_struct)); int rc; if(rc = pthread_mutex_init(&(token->mutex), NULL)) { free(token); return NULL; } if(rc = pthread_cond_init(&(token->condition), NULL)) { pthread_mutex_destroy( &(token->mutex) ); free(token); return NULL; } token->semCount = lInitialCount; return token; } BOOL CloseHandle( HANDLE hObject ) { sem_private token = (sem_private)hObject; pthread_mutex_destroy(&(token->mutex)); pthread_cond_destroy(&(token->condition)); free(hObject); return TRUE; } DWORD WaitForSingleObject( HANDLE hHandle, DWORD dwMilliseconds ) { int rc; sem_private token = (sem_private)hHandle; if(dwMilliseconds == INFINITE){ if (rc = pthread_mutex_lock(&(token->mutex))) return WAIT_FAILED; while (token->semCount <= 0) { rc = pthread_cond_wait(&(token->condition), &(token->mutex)); if (rc && errno != EINTR ) break; } token->semCount--; if (rc = pthread_mutex_unlock(&(token->mutex))) return WAIT_FAILED; } else{ struct timespec tm; struct timeb tp; long sec, millisec; if (rc = pthread_mutex_lock(&(token->mutex))) return WAIT_FAILED; sec = dwMilliseconds / 1000; millisec = dwMilliseconds % 1000; ftime( &tp ); tp.time += sec; tp.millitm += millisec; if( tp.millitm > 999 ) { tp.millitm -= 1000; tp.time++; } tm.tv_sec = tp.time; tm.tv_nsec = tp.millitm * 1000000 ; while (token->semCount <= 0) { rc = pthread_cond_timedwait(&(token->condition), &(token->mutex), &tm); if (rc && (errno != EINTR) ) break; } if ( rc ) { if ( pthread_mutex_unlock(&(token->mutex)) ) return WAIT_FAILED; if ( rc == ETIMEDOUT) /* we have a time out */ return WAIT_TIMEOUT; return WAIT_FAILED; } token->semCount--; if (rc = pthread_mutex_unlock(&(token->mutex))) return WAIT_FAILED; return WAIT_OBJECT_0; } } BOOL ReleaseSemaphore( HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount ) { if(hSemaphore == NULL) return FALSE; sem_private token = (sem_private)hSemaphore; int rc; if (rc = pthread_mutex_lock(&(token->mutex))) return FALSE; token->semCount += lReleaseCount; if (rc = pthread_mutex_unlock(&(token->mutex))) return FALSE; if (rc = pthread_cond_signal(&(token->condition))) return FALSE; return TRUE; } HANDLE CreateThread( LPSECURITY_ATTRIBUTES lpThreadAttributes, DWORD dwStackSize, LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId ) { int rc; if(rc = pthread_create((pthread_t*)lpThreadId, NULL, lpStartAddress, lpParameter)) return NULL; return (HANDLE)(*lpThreadId); } #endif