libfreerdp-utils: replace internal wait_obj implementation

This commit is contained in:
Marc-André Moreau 2012-11-26 18:02:41 -05:00
parent 6424599639
commit 57d4a07af9
6 changed files with 152 additions and 144 deletions

View File

@ -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)++;
}

View File

@ -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 */

View File

@ -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);

View File

@ -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];
}

View File

@ -40,6 +40,7 @@
struct winpr_event
{
int pipe_fd[2];
BOOL bAttached;
BOOL bManualReset;
};
typedef struct winpr_event WINPR_EVENT;

View File

@ -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)