BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode) { ULONG Type; WINPR_HANDLE* Object; WINPR_THREAD* thread; if (!winpr_Handle_GetInfo(hThread, &Type, &Object)) return FALSE; thread = (WINPR_THREAD*) Object; thread->exited = TRUE; thread->dwExitCode = dwExitCode; if (pthread_mutex_lock(&thread->mutex)) return FALSE; #ifndef ANDROID pthread_cancel(thread->thread); #else WLog_ERR(TAG, "Function not supported on this platform!"); #endif if (pthread_mutex_unlock(&thread->mutex)) return FALSE; set_event(thread); return TRUE; }
BOOL SetEvent(HANDLE hEvent) { ULONG Type; PVOID Object; int length; BOOL status; WINPR_EVENT* event; status = FALSE; EnterCriticalSection(&cs); if (winpr_Handle_GetInfo(hEvent, &Type, &Object)) { event = (WINPR_EVENT*) Object; if (!(WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)) { length = write(event->pipe_fd[1], "-", 1); if (length == 1) status = TRUE; } else { status = TRUE; } } LeaveCriticalSection(&cs); return status; }
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hFile, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_ANONYMOUS_PIPE) { int status; int write_fd; write_fd = (int) ((ULONG_PTR) Object); status = write(write_fd, lpBuffer, nNumberOfBytesToWrite); *lpNumberOfBytesWritten = status; return TRUE; } return FALSE; }
DWORD ResumeThread(HANDLE hThread) { ULONG Type; WINPR_HANDLE* Object; WINPR_THREAD* thread; if (!winpr_Handle_GetInfo(hThread, &Type, &Object)) return (DWORD) - 1; thread = (WINPR_THREAD*) Object; if (pthread_mutex_lock(&thread->mutex)) return (DWORD) - 1; if (!thread->started) { if (!winpr_StartThread(thread)) { pthread_mutex_unlock(&thread->mutex); return (DWORD) - 1; } } else WLog_WARN(TAG, "Thread already started!"); if (pthread_mutex_unlock(&thread->mutex)) return (DWORD) - 1; return 0; }
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hFile, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_ANONYMOUS_PIPE) { int status; int read_fd; read_fd = (int) ((ULONG_PTR) Object); status = read(read_fd, lpBuffer, nNumberOfBytesToRead); *lpNumberOfBytesRead = status; return TRUE; } return FALSE; }
BOOL ResetEvent(HANDLE hEvent) { ULONG Type; WINPR_HANDLE* Object; int length; BOOL status = TRUE; WINPR_EVENT* event; if (!winpr_Handle_GetInfo(hEvent, &Type, &Object)) return FALSE; event = (WINPR_EVENT*) Object; while (status && WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) { do { #ifdef HAVE_SYS_EVENTFD_H eventfd_t value; length = eventfd_read(event->pipe_fd[0], &value); #else length = read(event->pipe_fd[0], &length, 1); #endif } while ((length < 0) && (errno == EINTR)); if (length < 0) status = FALSE; } return status; }
int GetEventFileDescriptor(HANDLE hEvent) { #ifndef _WIN32 ULONG Type; PVOID Object; WINPR_EVENT* event; if (!winpr_Handle_GetInfo(hEvent, &Type, &Object)) return -1; event = (WINPR_EVENT*) Object; if (Type == HANDLE_TYPE_NAMED_PIPE) { WINPR_NAMED_PIPE *named = (WINPR_NAMED_PIPE *)hEvent; if (named->ServerMode) { return named->serverfd; } else { return named->clientfd; } } return event->pipe_fd[0]; #else return -1; #endif }
BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, LPOVERLAPPED lpOverlapped) { ULONG Type; WINPR_HANDLE *handle; if (hFile == INVALID_HANDLE_VALUE) return FALSE; /* * from http://msdn.microsoft.com/en-us/library/windows/desktop/aa365467%28v=vs.85%29.aspx * lpNumberOfBytesRead can be NULL only when the lpOverlapped parameter is not NULL. */ if (!lpNumberOfBytesRead && !lpOverlapped) return FALSE; if (!winpr_Handle_GetInfo(hFile, &Type, &handle)) return FALSE; handle = (WINPR_HANDLE *)hFile; if (handle->ops->ReadFile) return handle->ops->ReadFile(handle, lpBuffer, nNumberOfBytesToRead, lpNumberOfBytesRead, lpOverlapped); WLog_ERR(TAG, "ReadFile operation not implemented"); return FALSE; }
BOOL ResetEvent(HANDLE hEvent) { ULONG Type; PVOID Object; int length; BOOL status; WINPR_EVENT* event; status = FALSE; EnterCriticalSection(&cs); if (winpr_Handle_GetInfo(hEvent, &Type, &Object)) { event = (WINPR_EVENT*) Object; while (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) { length = read(event->pipe_fd[0], &length, 1); if (length == 1) status = TRUE; if (length != 1) break; } } LeaveCriticalSection(&cs); return status; }
BOOL GetExitCodeThread(HANDLE hThread, LPDWORD lpExitCode) { ULONG Type; WINPR_HANDLE* Object; WINPR_THREAD* thread; if (!winpr_Handle_GetInfo(hThread, &Type, &Object)) return FALSE; thread = (WINPR_THREAD*) Object; *lpExitCode = thread->dwExitCode; return TRUE; }
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hFile, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_ANONYMOUS_PIPE) { int status; WINPR_PIPE* pipe; pipe = (WINPR_PIPE*) Object; status = write(pipe->fd, lpBuffer, nNumberOfBytesToWrite); *lpNumberOfBytesWritten = status; return TRUE; } else if (Type == HANDLE_TYPE_NAMED_PIPE) { int status; WINPR_NAMED_PIPE* pipe; pipe = (WINPR_NAMED_PIPE*) Object; status = nNumberOfBytesToWrite; if (pipe->clientfd != -1) status = write(pipe->clientfd, lpBuffer, nNumberOfBytesToWrite); else return FALSE; if (status < 0) { *lpNumberOfBytesWritten = 0; return FALSE; } *lpNumberOfBytesWritten = status; return TRUE; } return FALSE; }
int SetEventFileDescriptor(HANDLE hEvent, int FileDescriptor) { #ifndef _WIN32 ULONG Type; PVOID Object; WINPR_EVENT* event; if (!winpr_Handle_GetInfo(hEvent, &Type, &Object)) return -1; event = (WINPR_EVENT*) Object; event->pipe_fd[0] = FileDescriptor; return 0; #else return -1; #endif }
BOOL SetEvent(HANDLE hEvent) { ULONG Type; PVOID Object; int length; BOOL status; WINPR_EVENT* event; status = FALSE; EnterCriticalSection(&cs); if (winpr_Handle_GetInfo(hEvent, &Type, &Object)) { event = (WINPR_EVENT*) Object; #ifdef HAVE_EVENTFD_H eventfd_t val = 1; do { length = eventfd_write(event->pipe_fd[0], val); } while ((length < 0) && (errno == EINTR)); status = (length == 0) ? TRUE : FALSE; #else if (WaitForSingleObject(hEvent, 0) != WAIT_OBJECT_0) { length = write(event->pipe_fd[1], "-", 1); if (length == 1) status = TRUE; } else { status = TRUE; } #endif } LeaveCriticalSection(&cs); return status; }
BOOL SetWaitableTimerEx(HANDLE hTimer, const LARGE_INTEGER* lpDueTime, LONG lPeriod, PTIMERAPCROUTINE pfnCompletionRoutine, LPVOID lpArgToCompletionRoutine, PREASON_CONTEXT WakeContext, ULONG TolerableDelay) { ULONG Type; PVOID Object; WINPR_TIMER* timer; if (!winpr_Handle_GetInfo(hTimer, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_TIMER) { timer = (WINPR_TIMER*) Object; return TRUE; } return TRUE; }
BOOL ReleaseMutex(HANDLE hMutex) { ULONG Type; PVOID Object; WINPR_MUTEX* mutex; if (!winpr_Handle_GetInfo(hMutex, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_MUTEX) { mutex = (WINPR_MUTEX*) Object; pthread_mutex_unlock(&mutex->mutex); return TRUE; } return FALSE; }
/** * Sets */ void _comm_setServerSerialDriver(HANDLE hComm, SERIAL_DRIVER_ID driverId) { ULONG Type; PVOID Object; WINPR_COMM* pComm; if (!CommInitialized()) return; if (!winpr_Handle_GetInfo(hComm, &Type, &Object)) { CommLog_Print(WLOG_WARN, "_comm_setServerSerialDriver failure"); return; } pComm = (WINPR_COMM*)Object; pComm->serverSerialDriverId = driverId; }
int SetEventFileDescriptor(HANDLE hEvent, int FileDescriptor, ULONG mode) { #ifndef _WIN32 ULONG Type; WINPR_HANDLE* Object; WINPR_EVENT* event; if (!winpr_Handle_GetInfo(hEvent, &Type, &Object)) return -1; event = (WINPR_EVENT*) Object; event->bAttached = TRUE; event->Mode = mode; event->pipe_fd[0] = FileDescriptor; return 0; #else return -1; #endif }
BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, LPOVERLAPPED lpOverlapped) { ULONG Type; WINPR_HANDLE *handle; if (hFile == INVALID_HANDLE_VALUE) return FALSE; if (!winpr_Handle_GetInfo(hFile, &Type, &handle)) return FALSE; handle = (WINPR_HANDLE *)hFile; if (handle->ops->WriteFile) return handle->ops->WriteFile(handle, lpBuffer, nNumberOfBytesToWrite, lpNumberOfBytesWritten, lpOverlapped); WLog_ERR(TAG, "ReadFile operation not implemented"); return FALSE; }
BOOL TerminateThread(HANDLE hThread, DWORD dwExitCode) { ULONG Type; PVOID Object; WINPR_THREAD* thread; if (!winpr_Handle_GetInfo(hThread, &Type, &Object)) return 0; thread = (WINPR_THREAD*) Object; pthread_mutex_lock(&thread->mutex); pthread_cancel(thread->thread); pthread_mutex_unlock(&thread->mutex); return TRUE; }
BOOL ResetEvent(HANDLE hEvent) { ULONG Type; PVOID Object; int length; BOOL status; WINPR_EVENT* event; status = FALSE; EnterCriticalSection(&cs); if (winpr_Handle_GetInfo(hEvent, &Type, &Object)) { event = (WINPR_EVENT*) Object; while (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0) { #ifdef HAVE_EVENTFD_H eventfd_t value; do { length = eventfd_read(event->pipe_fd[0], &value); } while ((length < 0) && (errno == EINTR)); if ((length > 0) && (!status)) status = TRUE; #else length = read(event->pipe_fd[0], &length, 1); if ((length == 1) && (!status)) status = TRUE; #endif } } LeaveCriticalSection(&cs); return status; }
BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hSemaphore, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_SEMAPHORE) { #if defined __APPLE__ semaphore_signal(*((winpr_sem_t*) Object)); #else sem_post((winpr_sem_t*) Object); #endif return TRUE; } return FALSE; }
DWORD ResumeThread(HANDLE hThread) { ULONG Type; PVOID Object; WINPR_THREAD* thread; if (!winpr_Handle_GetInfo(hThread, &Type, &Object)) return 0; thread = (WINPR_THREAD*) Object; pthread_mutex_lock(&thread->mutex); if (!thread->started) winpr_StartThread(thread); pthread_mutex_unlock(&thread->mutex); return 0; }
BOOL ReleaseSemaphore(HANDLE hSemaphore, LONG lReleaseCount, LPLONG lpPreviousCount) { ULONG Type; PVOID Object; WINPR_SEMAPHORE* semaphore; if (!winpr_Handle_GetInfo(hSemaphore, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_SEMAPHORE) { semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { while (lReleaseCount > 0) { if (write(semaphore->pipe_fd[1], "-", 1) != 1) return FALSE; lReleaseCount--; } } #else #if defined __APPLE__ semaphore_signal(*((winpr_sem_t*) semaphore->sem)); #else sem_post((winpr_sem_t*) semaphore->sem); #endif #endif return TRUE; } return FALSE; }
BOOL ReleaseMutex(HANDLE hMutex) { ULONG Type; WINPR_HANDLE* Object; if (!winpr_Handle_GetInfo(hMutex, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex = (WINPR_MUTEX*) Object; int rc = pthread_mutex_unlock(&mutex->mutex); if (rc) { WLog_ERR(TAG, "pthread_mutex_unlock failed with %s [%d]", strerror(rc), rc); return FALSE; } return TRUE; } return FALSE; }
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hHandle, &Type, &Object)) return WAIT_FAILED; if (Type == HANDLE_TYPE_THREAD) { int status; WINPR_THREAD* thread; void* thread_status = NULL; if (dwMilliseconds != INFINITE) printf("WaitForSingleObject: timeout not implemented for thread wait\n"); thread = (WINPR_THREAD*) Object; status = pthread_join(thread->thread, &thread_status); if (status != 0) printf("WaitForSingleObject: pthread_join failure: %d\n", status); } else if (Type == HANDLE_TYPE_MUTEX) { if (dwMilliseconds != INFINITE) printf("WaitForSingleObject: timeout not implemented for mutex wait\n"); pthread_mutex_lock((pthread_mutex_t*) Object); } else if (Type == HANDLE_TYPE_EVENT) { int status; fd_set rfds; WINPR_EVENT* event; struct timeval timeout; event = (WINPR_EVENT*) Object; FD_ZERO(&rfds); FD_SET(event->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { int status; int length; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(semaphore->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; length = read(semaphore->pipe_fd[0], &length, 1); if (length != 1) return FALSE; } #else #if defined __APPLE__ semaphore_wait(*((winpr_sem_t*) semaphore->sem)); #else sem_wait((winpr_sem_t*) semaphore->sem); #endif #endif } else { printf("WaitForSingleObject: unknown handle type %d\n", Type); } return WAIT_OBJECT_0; }
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds) { int fd = -1; int maxfd; int index; int status; fd_set fds; ULONG Type; PVOID Object; struct timeval timeout; if (!nCount) return WAIT_FAILED; maxfd = 0; FD_ZERO(&fds); ZeroMemory(&timeout, sizeof(timeout)); if (bWaitAll) printf("WaitForMultipleObjects: bWaitAll not yet implemented\n"); for (index = 0; index < nCount; index++) { if (!winpr_Handle_GetInfo(lpHandles[index], &Type, &Object)) return WAIT_FAILED; if (Type == HANDLE_TYPE_EVENT) { fd = ((WINPR_EVENT*) Object)->pipe_fd[0]; } else if (Type == HANDLE_TYPE_SEMAPHORE) { #ifdef WINPR_PIPE_SEMAPHORE fd = ((WINPR_SEMAPHORE*) Object)->pipe_fd[0]; #else return WAIT_FAILED; #endif } else { return WAIT_FAILED; } FD_SET(fd, &fds); if (fd > maxfd) maxfd = fd; } if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(maxfd + 1, &fds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status == 0) return WAIT_TIMEOUT; for (index = 0; index < nCount; index++) { winpr_Handle_GetInfo(lpHandles[index], &Type, &Object); if (Type == HANDLE_TYPE_EVENT) fd = ((WINPR_EVENT*) Object)->pipe_fd[0]; else if (Type == HANDLE_TYPE_SEMAPHORE) fd = ((WINPR_SEMAPHORE*) Object)->pipe_fd[0]; if (FD_ISSET(fd, &fds)) { if (Type == HANDLE_TYPE_SEMAPHORE) { int length = read(fd, &length, 1); if (length != 1) return WAIT_FAILED; } return (WAIT_OBJECT_0 + index); } } return WAIT_FAILED; }
BOOL CloseHandle(HANDLE hObject) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hObject, &Type, &Object)) return FALSE; if (Type == HANDLE_TYPE_THREAD) { WINPR_THREAD* thread; thread = (WINPR_THREAD*) Object; free(thread); return TRUE; } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) Object; pthread_mutex_destroy(&mutex->mutex); free(Object); return TRUE; } else if (Type == HANDLE_TYPE_EVENT) { WINPR_EVENT* event; event = (WINPR_EVENT*) Object; if (!event->bAttached) { if (event->pipe_fd[0] != -1) { close(event->pipe_fd[0]); event->pipe_fd[0] = -1; } if (event->pipe_fd[1] != -1) { close(event->pipe_fd[1]); event->pipe_fd[1] = -1; } } free(Object); return TRUE; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { close(semaphore->pipe_fd[0]); semaphore->pipe_fd[0] = -1; if (semaphore->pipe_fd[1] != -1) { close(semaphore->pipe_fd[1]); semaphore->pipe_fd[1] = -1; } } #else #if defined __APPLE__ semaphore_destroy(mach_task_self(), *((winpr_sem_t*) semaphore->sem)); #else sem_destroy((winpr_sem_t*) semaphore->sem); #endif #endif free(Object); return TRUE; } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer; timer = (WINPR_TIMER*) Object; #ifdef __linux__ if (timer->fd != -1) close(timer->fd); #endif free(Object); return TRUE; } else if (Type == HANDLE_TYPE_ANONYMOUS_PIPE) { WINPR_PIPE* pipe; pipe = (WINPR_PIPE*) Object; if (pipe->fd != -1) { close(pipe->fd); } free(Object); return TRUE; } else if (Type == HANDLE_TYPE_NAMED_PIPE) { WINPR_NAMED_PIPE* pipe; pipe = (WINPR_NAMED_PIPE*) Object; if (pipe->clientfd != -1) close(pipe->clientfd); if (pipe->serverfd != -1) close(pipe->serverfd); free(Object); return TRUE; } return FALSE; }
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hHandle, &Type, &Object)) return WAIT_FAILED; if (Type == HANDLE_TYPE_THREAD) { int status = 0; WINPR_THREAD* thread; void* thread_status = NULL; thread = (WINPR_THREAD*) Object; if (thread->started) { if (dwMilliseconds != INFINITE) { #if HAVE_PTHREAD_GNU_EXT struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); #else fprintf(stderr, "[ERROR] %s: Thread timeouts not implemented.\n", __func__); assert(0); #endif } else status = pthread_join(thread->thread, &thread_status); if (status != 0) fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n", status, strerror(status)); if (thread_status) thread->dwExitCode = ((DWORD) (size_t) thread_status); } } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) Object; #if HAVE_PTHREAD_GNU_EXT if (dwMilliseconds != INFINITE) { struct timespec timeout; clock_gettime(CLOCK_REALTIME, &timeout); ts_add_ms(&timeout, dwMilliseconds); pthread_mutex_timedlock(&mutex->mutex, &timeout); } else #endif { pthread_mutex_lock(&mutex->mutex); } } else if (Type == HANDLE_TYPE_EVENT) { int status; fd_set rfds; WINPR_EVENT* event; struct timeval timeout; event = (WINPR_EVENT*) Object; FD_ZERO(&rfds); FD_SET(event->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { int status; int length; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(semaphore->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; length = read(semaphore->pipe_fd[0], &length, 1); if (length != 1) return WAIT_FAILED; } #else #if defined __APPLE__ semaphore_wait(*((winpr_sem_t*) semaphore->sem)); #else sem_wait((winpr_sem_t*) semaphore->sem); #endif #endif } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer; timer = (WINPR_TIMER*) Object; #ifdef HAVE_EVENTFD_H if (timer->fd != -1) { int status; fd_set rfds; UINT64 expirations; struct timeval timeout; FD_ZERO(&rfds); FD_SET(timer->fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(timer->fd + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; status = read(timer->fd, (void*) &expirations, sizeof(UINT64)); if (status != 8) return WAIT_TIMEOUT; } else { return WAIT_FAILED; } #else return WAIT_FAILED; #endif } else if (Type == HANDLE_TYPE_NAMED_PIPE) { int status; fd_set rfds; struct timeval timeout; WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; FD_ZERO(&rfds); FD_SET(pipe->clientfd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_usec = dwMilliseconds * 1000; } status = select(pipe->clientfd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); if (status < 0) return WAIT_FAILED; if (status != 1) return WAIT_TIMEOUT; } else { fprintf(stderr, "WaitForSingleObject: unknown handle type %lu\n", Type); } return WAIT_OBJECT_0; }
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds) { int fd = -1; int maxfd; int index; int status; fd_set fds; ULONG Type; PVOID Object; struct timeval timeout; if (!nCount) { fprintf(stderr, "WaitForMultipleObjects: invalid handles count\n"); return WAIT_FAILED; } maxfd = 0; FD_ZERO(&fds); ZeroMemory(&timeout, sizeof(timeout)); if (bWaitAll) { fprintf(stderr, "WaitForMultipleObjects: bWaitAll not yet implemented\n"); assert(0); } for (index = 0; index < nCount; index++) { if (!winpr_Handle_GetInfo(lpHandles[index], &Type, &Object)) { fprintf(stderr, "WaitForMultipleObjects: invalid handle\n"); return WAIT_FAILED; } if (Type == HANDLE_TYPE_EVENT) { fd = ((WINPR_EVENT*) Object)->pipe_fd[0]; if (fd == -1) { fprintf(stderr, "WaitForMultipleObjects: invalid event file descriptor\n"); return WAIT_FAILED; } } else if (Type == HANDLE_TYPE_SEMAPHORE) { #ifdef WINPR_PIPE_SEMAPHORE fd = ((WINPR_SEMAPHORE*) Object)->pipe_fd[0]; #else fprintf(stderr, "WaitForMultipleObjects: semaphore not supported\n"); return WAIT_FAILED; #endif } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer = (WINPR_TIMER*) Object; fd = timer->fd; if (fd == -1) { fprintf(stderr, "WaitForMultipleObjects: invalid timer file descriptor\n"); return WAIT_FAILED; } } else if (Type == HANDLE_TYPE_NAMED_PIPE) { WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd; if (fd == -1) { fprintf(stderr, "WaitForMultipleObjects: invalid timer file descriptor\n"); return WAIT_FAILED; } } else { fprintf(stderr, "WaitForMultipleObjects: unknown handle type %lu\n", Type); return WAIT_FAILED; } if (fd == -1) { fprintf(stderr, "WaitForMultipleObjects: invalid file descriptor\n"); return WAIT_FAILED; } FD_SET(fd, &fds); if (fd > maxfd) maxfd = fd; } if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(maxfd + 1, &fds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && errno == EINTR); if (status < 0) { fprintf(stderr, "WaitForMultipleObjects: select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status == 0) return WAIT_TIMEOUT; for (index = 0; index < nCount; index++) { winpr_Handle_GetInfo(lpHandles[index], &Type, &Object); if (Type == HANDLE_TYPE_EVENT) { fd = ((WINPR_EVENT*) Object)->pipe_fd[0]; } else if (Type == HANDLE_TYPE_SEMAPHORE) { fd = ((WINPR_SEMAPHORE*) Object)->pipe_fd[0]; } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer = (WINPR_TIMER*) Object; fd = timer->fd; } else if (Type == HANDLE_TYPE_NAMED_PIPE) { WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd; } if (FD_ISSET(fd, &fds)) { if (Type == HANDLE_TYPE_SEMAPHORE) { int length; length = read(fd, &length, 1); if (length != 1) { fprintf(stderr, "WaitForMultipleObjects: semaphore read() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } } else if (Type == HANDLE_TYPE_TIMER) { int length; UINT64 expirations; length = read(fd, (void*) &expirations, sizeof(UINT64)); if (length != 8) { if (length == -1) { if (errno == ETIMEDOUT) return WAIT_TIMEOUT; fprintf(stderr, "WaitForMultipleObjects: timer read() failure [%d] %s\n", errno, strerror(errno)); } else { fprintf(stderr, "WaitForMultipleObjects: timer read() failure - incorrect number of bytes read"); } return WAIT_FAILED; } } return (WAIT_OBJECT_0 + index); } } fprintf(stderr, "WaitForMultipleObjects: failed (unknown error)\n"); return WAIT_FAILED; }
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) { ULONG Type; PVOID Object; if (!winpr_Handle_GetInfo(hHandle, &Type, &Object)) { fprintf(stderr, "WaitForSingleObject failed: invalid hHandle.\n"); return WAIT_FAILED; } if (Type == HANDLE_TYPE_THREAD) { int status = 0; WINPR_THREAD* thread; void* thread_status = NULL; thread = (WINPR_THREAD*) Object; if (thread->started) { if (dwMilliseconds != INFINITE) { struct timespec timeout; /* pthread_timedjoin_np returns ETIMEDOUT in case the timeout is 0, * so set it to the smallest value to get a proper return value. */ if (dwMilliseconds == 0) dwMilliseconds ++; clock_gettime(CLOCK_MONOTONIC, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_timedjoin_np(thread->thread, &thread_status, &timeout); if (ETIMEDOUT == status) return WAIT_TIMEOUT; } else status = pthread_join(thread->thread, &thread_status); if (status != 0) { fprintf(stderr, "WaitForSingleObject: pthread_join failure: [%d] %s\n", status, strerror(status)); } if (thread_status) thread->dwExitCode = ((DWORD) (size_t) thread_status); } } else if (Type == HANDLE_TYPE_PROCESS) { WINPR_PROCESS* process; process = (WINPR_PROCESS*) Object; if (waitpid(process->pid, &(process->status), 0) != -1) { fprintf(stderr, "WaitForSingleObject: waitpid failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } process->dwExitCode = (DWORD) process->status; } else if (Type == HANDLE_TYPE_MUTEX) { WINPR_MUTEX* mutex; mutex = (WINPR_MUTEX*) Object; if (dwMilliseconds != INFINITE) { int status; struct timespec timeout; clock_gettime(CLOCK_MONOTONIC, &timeout); ts_add_ms(&timeout, dwMilliseconds); status = pthread_mutex_timedlock(&mutex->mutex, &timeout); if (ETIMEDOUT == status) return WAIT_TIMEOUT; } else { pthread_mutex_lock(&mutex->mutex); } } else if (Type == HANDLE_TYPE_EVENT) { int status; fd_set rfds; WINPR_EVENT* event; struct timeval timeout; event = (WINPR_EVENT*) Object; FD_ZERO(&rfds); FD_SET(event->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(event->pipe_fd[0] + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: event select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; } else if (Type == HANDLE_TYPE_SEMAPHORE) { WINPR_SEMAPHORE* semaphore; semaphore = (WINPR_SEMAPHORE*) Object; #ifdef WINPR_PIPE_SEMAPHORE if (semaphore->pipe_fd[0] != -1) { int status; int length; fd_set rfds; struct timeval timeout; FD_ZERO(&rfds); FD_SET(semaphore->pipe_fd[0], &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(semaphore->pipe_fd[0] + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: semaphore select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; length = read(semaphore->pipe_fd[0], &length, 1); if (length != 1) { fprintf(stderr, "WaitForSingleObject: semaphore read failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } } #else #if defined __APPLE__ semaphore_wait(*((winpr_sem_t*) semaphore->sem)); #else sem_wait((winpr_sem_t*) semaphore->sem); #endif #endif } else if (Type == HANDLE_TYPE_TIMER) { WINPR_TIMER* timer; timer = (WINPR_TIMER*) Object; #ifdef HAVE_EVENTFD_H if (timer->fd != -1) { int status; fd_set rfds; UINT64 expirations; struct timeval timeout; FD_ZERO(&rfds); FD_SET(timer->fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(timer->fd + 1, &rfds, 0, 0, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: timer select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) return WAIT_TIMEOUT; status = read(timer->fd, (void*) &expirations, sizeof(UINT64)); if (status != 8) { if (status == -1) { if (errno == ETIMEDOUT) return WAIT_TIMEOUT; fprintf(stderr, "WaitForSingleObject: timer read() failure [%d] %s\n", errno, strerror(errno)); } else { fprintf(stderr, "WaitForSingleObject: timer read() failure - incorrect number of bytes read"); } return WAIT_FAILED; } } else { fprintf(stderr, "WaitForSingleObject: invalid timer file descriptor\n"); return WAIT_FAILED; } #else fprintf(stderr, "WaitForSingleObject: file descriptors not supported\n"); return WAIT_FAILED; #endif } else if (Type == HANDLE_TYPE_NAMED_PIPE) { int fd; int status; fd_set rfds; struct timeval timeout; WINPR_NAMED_PIPE* pipe = (WINPR_NAMED_PIPE*) Object; fd = (pipe->ServerMode) ? pipe->serverfd : pipe->clientfd; if (fd == -1) { fprintf(stderr, "WaitForSingleObject: invalid pipe file descriptor\n"); return WAIT_FAILED; } FD_ZERO(&rfds); FD_SET(fd, &rfds); ZeroMemory(&timeout, sizeof(timeout)); if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0)) { timeout.tv_sec = dwMilliseconds / 1000; timeout.tv_usec = (dwMilliseconds % 1000) * 1000; } do { status = select(fd + 1, &rfds, NULL, NULL, (dwMilliseconds == INFINITE) ? NULL : &timeout); } while (status < 0 && (errno == EINTR)); if (status < 0) { fprintf(stderr, "WaitForSingleObject: named pipe select() failure [%d] %s\n", errno, strerror(errno)); return WAIT_FAILED; } if (status != 1) { return WAIT_TIMEOUT; } } else { fprintf(stderr, "WaitForSingleObject: unknown handle type %lu\n", Type); } return WAIT_OBJECT_0; }