libfreerdp-utils: replace internal wait_obj implementation
This commit is contained in:
parent
6424599639
commit
57d4a07af9
@ -26,6 +26,7 @@
|
||||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/synch.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#include <freerdp/utils/wait_obj.h>
|
||||
@ -40,12 +41,7 @@
|
||||
|
||||
struct wait_obj
|
||||
{
|
||||
#ifdef _WIN32
|
||||
HANDLE event;
|
||||
#else
|
||||
int pipe_fd[2];
|
||||
#endif
|
||||
int attached;
|
||||
};
|
||||
|
||||
struct wait_obj* wait_obj_new(void)
|
||||
@ -55,20 +51,7 @@ struct wait_obj* wait_obj_new(void)
|
||||
obj = (struct wait_obj*) malloc(sizeof(struct wait_obj));
|
||||
ZeroMemory(obj, sizeof(struct wait_obj));
|
||||
|
||||
obj->attached = 0;
|
||||
#ifdef _WIN32
|
||||
obj->event = CreateEvent(NULL, TRUE, FALSE, NULL);
|
||||
#else
|
||||
obj->pipe_fd[0] = -1;
|
||||
obj->pipe_fd[1] = -1;
|
||||
|
||||
if (pipe(obj->pipe_fd) < 0)
|
||||
{
|
||||
printf("wait_obj_new: pipe failed\n");
|
||||
free(obj);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
return obj;
|
||||
}
|
||||
@ -80,160 +63,63 @@ struct wait_obj* wait_obj_new_with_fd(void* fd)
|
||||
obj = (struct wait_obj*) malloc(sizeof(struct wait_obj));
|
||||
ZeroMemory(obj, sizeof(struct wait_obj));
|
||||
|
||||
obj->attached = 1;
|
||||
#ifdef _WIN32
|
||||
obj->event = fd;
|
||||
#else
|
||||
obj->pipe_fd[0] = (int)(long)fd;
|
||||
obj->pipe_fd[1] = -1;
|
||||
#endif
|
||||
obj->event = CreateFileDescriptorEvent(NULL, TRUE, FALSE, ((int) (long) fd));
|
||||
|
||||
return obj;
|
||||
}
|
||||
|
||||
void wait_obj_free(struct wait_obj* obj)
|
||||
{
|
||||
if (obj)
|
||||
{
|
||||
if (obj->attached == 0)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
if (obj->event)
|
||||
{
|
||||
CloseHandle(obj->event);
|
||||
obj->event = NULL;
|
||||
}
|
||||
#else
|
||||
if (obj->pipe_fd[0] != -1)
|
||||
{
|
||||
close(obj->pipe_fd[0]);
|
||||
obj->pipe_fd[0] = -1;
|
||||
}
|
||||
if (obj->pipe_fd[1] != -1)
|
||||
{
|
||||
close(obj->pipe_fd[1]);
|
||||
obj->pipe_fd[1] = -1;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
free(obj);
|
||||
}
|
||||
CloseHandle(obj->event);
|
||||
}
|
||||
|
||||
int wait_obj_is_set(struct wait_obj* obj)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
return (WaitForSingleObject(obj->event, 0) == WAIT_OBJECT_0);
|
||||
#else
|
||||
fd_set rfds;
|
||||
int num_set;
|
||||
struct timeval time;
|
||||
|
||||
FD_ZERO(&rfds);
|
||||
FD_SET(obj->pipe_fd[0], &rfds);
|
||||
memset(&time, 0, sizeof(time));
|
||||
num_set = select(obj->pipe_fd[0] + 1, &rfds, 0, 0, &time);
|
||||
return (num_set == 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
void wait_obj_set(struct wait_obj* obj)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
SetEvent(obj->event);
|
||||
#else
|
||||
int len;
|
||||
|
||||
if (wait_obj_is_set(obj))
|
||||
return;
|
||||
|
||||
len = write(obj->pipe_fd[1], "sig", 4);
|
||||
|
||||
if (len != 4)
|
||||
printf("wait_obj_set: error\n");
|
||||
#endif
|
||||
}
|
||||
|
||||
void wait_obj_clear(struct wait_obj* obj)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
ResetEvent(obj->event);
|
||||
#else
|
||||
int len;
|
||||
|
||||
while (wait_obj_is_set(obj))
|
||||
{
|
||||
len = read(obj->pipe_fd[0], &len, 4);
|
||||
if (len != 4)
|
||||
printf("wait_obj_clear: error\n");
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
int wait_obj_select(struct wait_obj** listobj, int numobj, int timeout)
|
||||
{
|
||||
int index;
|
||||
int status;
|
||||
#ifndef _WIN32
|
||||
int max;
|
||||
int sock;
|
||||
fd_set fds;
|
||||
struct timeval time;
|
||||
struct timeval* ptime;
|
||||
HANDLE* handles;
|
||||
|
||||
ptime = 0;
|
||||
if (timeout >= 0)
|
||||
{
|
||||
time.tv_sec = timeout / 1000;
|
||||
time.tv_usec = (timeout * 1000) % 1000000;
|
||||
ptime = &time;
|
||||
}
|
||||
|
||||
max = 0;
|
||||
FD_ZERO(&fds);
|
||||
if (listobj)
|
||||
{
|
||||
for (index = 0; index < numobj; index++)
|
||||
{
|
||||
sock = listobj[index]->pipe_fd[0];
|
||||
FD_SET(sock, &fds);
|
||||
|
||||
if (sock > max)
|
||||
max = sock;
|
||||
}
|
||||
}
|
||||
status = select(max + 1, &fds, 0, 0, ptime);
|
||||
#else
|
||||
HANDLE* hnds;
|
||||
|
||||
hnds = (HANDLE*) malloc(sizeof(HANDLE) * (numobj + 1));
|
||||
ZeroMemory(hnds, sizeof(HANDLE) * (numobj + 1));
|
||||
handles = (HANDLE*) malloc(sizeof(HANDLE) * (numobj + 1));
|
||||
ZeroMemory(handles, sizeof(HANDLE) * (numobj + 1));
|
||||
|
||||
for (index = 0; index < numobj; index++)
|
||||
{
|
||||
hnds[index] = listobj[index]->event;
|
||||
}
|
||||
handles[index] = listobj[index]->event;
|
||||
|
||||
if (WaitForMultipleObjects(numobj, hnds, FALSE, timeout) == WAIT_FAILED)
|
||||
if (WaitForMultipleObjects(numobj, handles, FALSE, timeout) == WAIT_FAILED)
|
||||
status = -1;
|
||||
else
|
||||
status = 0;
|
||||
free(hnds);
|
||||
#endif
|
||||
|
||||
free(handles);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
void wait_obj_get_fds(struct wait_obj* obj, void** fds, int* count)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
fds[*count] = (void*) obj->event;
|
||||
#else
|
||||
if (obj->pipe_fd[0] == -1)
|
||||
int fd;
|
||||
|
||||
fd = GetEventFileDescriptor(obj->event);
|
||||
|
||||
if (fd == -1)
|
||||
return;
|
||||
|
||||
fds[*count] = (void*)(long) obj->pipe_fd[0];
|
||||
#endif
|
||||
fds[*count] = ((void*) (long) fd);
|
||||
|
||||
(*count)++;
|
||||
}
|
||||
|
@ -249,5 +249,20 @@ WINPR_API BOOL CancelWaitableTimer(HANDLE hTimer);
|
||||
|
||||
#endif
|
||||
|
||||
/* Extended API */
|
||||
|
||||
WINPR_API HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes,
|
||||
BOOL bManualReset, BOOL bInitialState, int FileDescriptor);
|
||||
WINPR_API HANDLE CreateFileDescriptorEventA(LPSECURITY_ATTRIBUTES lpEventAttributes,
|
||||
BOOL bManualReset, BOOL bInitialState, int FileDescriptor);
|
||||
|
||||
WINPR_API int GetEventFileDescriptor(HANDLE hEvent);
|
||||
|
||||
#ifdef UNICODE
|
||||
#define CreateFileDescriptorEvent CreateFileDescriptorEventW
|
||||
#else
|
||||
#define CreateFileDescriptorEvent CreateFileDescriptorEventA
|
||||
#endif
|
||||
|
||||
#endif /* WINPR_SYNCH_H */
|
||||
|
||||
|
@ -57,15 +57,18 @@ BOOL CloseHandle(HANDLE hObject)
|
||||
|
||||
event = (WINPR_EVENT*) Object;
|
||||
|
||||
if (event->pipe_fd[0] != -1)
|
||||
if (!event->bAttached)
|
||||
{
|
||||
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;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
winpr_Handle_Remove(Object);
|
||||
|
@ -51,6 +51,7 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
|
||||
|
||||
if (event)
|
||||
{
|
||||
event->bAttached = FALSE;
|
||||
event->bManualReset = bManualReset;
|
||||
|
||||
if (!event->bManualReset)
|
||||
@ -113,9 +114,9 @@ BOOL SetEvent(HANDLE hEvent)
|
||||
if (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
|
||||
return TRUE;
|
||||
|
||||
length = write(event->pipe_fd[1], "sig", 4);
|
||||
length = write(event->pipe_fd[1], "-", 1);
|
||||
|
||||
if (length != 4)
|
||||
if (length != 1)
|
||||
return FALSE;
|
||||
|
||||
return TRUE;
|
||||
@ -135,9 +136,9 @@ BOOL ResetEvent(HANDLE hEvent)
|
||||
|
||||
while (WaitForSingleObject(hEvent, 0) == WAIT_OBJECT_0)
|
||||
{
|
||||
length = read(event->pipe_fd[0], &length, 4);
|
||||
length = read(event->pipe_fd[0], &length, 1);
|
||||
|
||||
if (length != 4)
|
||||
if (length != 1)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -145,3 +146,48 @@ BOOL ResetEvent(HANDLE hEvent)
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
HANDLE CreateFileDescriptorEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, int FileDescriptor)
|
||||
{
|
||||
WINPR_EVENT* event;
|
||||
HANDLE handle = NULL;
|
||||
|
||||
event = (WINPR_EVENT*) malloc(sizeof(WINPR_EVENT));
|
||||
|
||||
if (event)
|
||||
{
|
||||
event->bAttached = TRUE;
|
||||
event->bManualReset = bManualReset;
|
||||
|
||||
if (!event->bManualReset)
|
||||
{
|
||||
printf("CreateFileDescriptorEventW: auto-reset events not yet implemented\n");
|
||||
}
|
||||
|
||||
event->pipe_fd[0] = FileDescriptor;
|
||||
event->pipe_fd[1] = -1;
|
||||
|
||||
handle = winpr_Handle_Insert(HANDLE_TYPE_EVENT, event);
|
||||
}
|
||||
|
||||
return handle;
|
||||
}
|
||||
|
||||
HANDLE CreateFileDescriptorEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, int FileDescriptor)
|
||||
{
|
||||
return CreateFileDescriptorEventW(lpEventAttributes, bManualReset, bInitialState, FileDescriptor);
|
||||
}
|
||||
|
||||
int GetEventFileDescriptor(HANDLE hEvent)
|
||||
{
|
||||
ULONG Type;
|
||||
PVOID Object;
|
||||
WINPR_EVENT* event;
|
||||
|
||||
if (!winpr_Handle_GetInfo(hEvent, &Type, &Object))
|
||||
return -1;
|
||||
|
||||
event = (WINPR_EVENT*) Object;
|
||||
|
||||
return event->pipe_fd[0];
|
||||
}
|
||||
|
@ -40,6 +40,7 @@
|
||||
struct winpr_event
|
||||
{
|
||||
int pipe_fd[2];
|
||||
BOOL bAttached;
|
||||
BOOL bManualReset;
|
||||
};
|
||||
typedef struct winpr_event WINPR_EVENT;
|
||||
|
@ -107,7 +107,64 @@ DWORD WaitForSingleObjectEx(HANDLE hHandle, DWORD dwMilliseconds, BOOL bAlertabl
|
||||
|
||||
DWORD WaitForMultipleObjects(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds)
|
||||
{
|
||||
return 0;
|
||||
int fd;
|
||||
int maxfd;
|
||||
int index;
|
||||
int status;
|
||||
fd_set fds;
|
||||
ULONG Type;
|
||||
PVOID Object;
|
||||
WINPR_EVENT* event;
|
||||
struct timeval timeout;
|
||||
|
||||
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)
|
||||
return WAIT_FAILED;
|
||||
|
||||
event = (WINPR_EVENT*) Object;
|
||||
fd = event->pipe_fd[0];
|
||||
|
||||
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);
|
||||
fd = ((WINPR_EVENT*) Object)->pipe_fd[0];
|
||||
|
||||
if (FD_ISSET(fd, &fds))
|
||||
return (WAIT_OBJECT_0 + index);
|
||||
}
|
||||
|
||||
return WAIT_FAILED;
|
||||
}
|
||||
|
||||
DWORD WaitForMultipleObjectsEx(DWORD nCount, const HANDLE* lpHandles, BOOL bWaitAll, DWORD dwMilliseconds, BOOL bAlertable)
|
||||
|
Loading…
Reference in New Issue
Block a user