channels/rdpdr/disk: replace thread utils by WinPR thread API
authorMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 23 Sep 2012 17:54:14 +0000 (13:54 -0400)
committerMarc-André Moreau <marcandre.moreau@gmail.com>
Sun, 23 Sep 2012 17:54:14 +0000 (13:54 -0400)
channels/rdpdr/client/disk/CMakeLists.txt
channels/rdpdr/client/disk/disk_main.c
channels/rdpdr/client/rdpdr_main.c
channels/rdpdr/client/smartcard/scard_main.c
libfreerdp/utils/svc_plugin.c
winpr/include/winpr/synch.h
winpr/include/winpr/thread.h
winpr/libwinpr/handle/table.c
winpr/libwinpr/synch/event.c
winpr/libwinpr/synch/wait.c
winpr/libwinpr/thread/thread.c

index aaac503..d6d7935 100644 (file)
 # See the License for the specific language governing permissions and
 # limitations under the License.
 
-set(DISK_SRCS
+set(MODULE_NAME "disk")
+set(MODULE_PREFIX "CHANNEL_DEVICE_DISK")
+
+set(${MODULE_PREFIX}_SRCS
        disk_file.c
        disk_file.h
        disk_main.c)
 
 include_directories(..)
 
-add_library(disk ${DISK_SRCS})
-set_target_properties(disk PROPERTIES PREFIX "")
+add_library(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
+set_target_properties(${MODULE_NAME} PROPERTIES PREFIX "")
 
 if(WITH_MONOLITHIC_BUILD)
-       target_link_libraries(disk freerdp)
+       set(${MODULE_PREFIX}_LIBS freerdp winpr)
 else()
-       target_link_libraries(disk freerdp-utils)
+       set(${MODULE_PREFIX}_LIBS freerdp-utils winpr-synch winpr-thread)
 endif()
 
-install(TARGETS disk DESTINATION ${FREERDP_PLUGIN_PATH})
+target_link_libraries(${MODULE_NAME} ${${MODULE_PREFIX}_LIBS})
+install(TARGETS ${MODULE_NAME} DESTINATION ${FREERDP_PLUGIN_PATH})
index 44126dd..5616b81 100644 (file)
 #include <freerdp/utils/stream.h>
 #include <freerdp/utils/unicode.h>
 #include <freerdp/utils/list.h>
-#include <freerdp/utils/thread.h>
 #include <freerdp/utils/svc_plugin.h>
 
+#include <winpr/synch.h>
+#include <winpr/thread.h>
+
 #include "rdpdr_constants.h"
 #include "rdpdr_types.h"
 #include "disk_file.h"
 
 typedef struct _DISK_DEVICE DISK_DEVICE;
+
 struct _DISK_DEVICE
 {
        DEVICE device;
@@ -54,15 +57,17 @@ struct _DISK_DEVICE
        char* path;
        LIST* files;
 
+       HANDLE mutex;
+       HANDLE thread;
        LIST* irp_list;
-       freerdp_thread* thread;
+       HANDLE irpEvent;
+       HANDLE stopEvent;
 
        DEVMAN* devman;
        pcRegisterDevice UnregisterDevice;
 };
 
-static uint32
-disk_map_posix_err(int fs_errno)
+static uint32 disk_map_posix_err(int fs_errno)
 {
        uint32 rc;
 
@@ -90,7 +95,9 @@ disk_map_posix_err(int fs_errno)
                        rc = STATUS_UNSUCCESSFUL;
                        break;
        }
+
        DEBUG_SVC("errno 0x%x mapped to 0x%x", fs_errno, rc);
+
        return rc;
 }
 
@@ -101,7 +108,8 @@ static DISK_FILE* disk_get_file_by_id(DISK_DEVICE* disk, uint32 id)
 
        for (item = disk->files->head; item; item = item->next)
        {
-               file = (DISK_FILE*)item->data;
+               file = (DISK_FILE*) item->data;
+
                if (file->id == id)
                        return file;
        }
@@ -238,7 +246,7 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
        }
        else
        {
-               buffer = (uint8*)xmalloc(Length);
+               buffer = (uint8*) xmalloc(Length);
                if (!disk_file_read(file, buffer, &Length))
                {
                        irp->IoStatus = STATUS_UNSUCCESSFUL;
@@ -255,11 +263,13 @@ static void disk_process_irp_read(DISK_DEVICE* disk, IRP* irp)
        }
 
        stream_write_uint32(irp->output, Length);
+
        if (Length > 0)
        {
                stream_check_size(irp->output, Length);
                stream_write(irp->output, buffer, Length);
        }
+
        xfree(buffer);
 
        irp->Complete(irp);
@@ -379,8 +389,8 @@ static void disk_process_irp_query_volume_information(DISK_DEVICE* disk, IRP* ir
        struct STATVFS svfst;
        struct STAT st;
        UNICONV* uniconv;
-       char *volumeLabel = {"FREERDP"};  /* TODO:: Add sub routine to correctly pick up Volume Label name for each O/S supported*/
-       char *diskType = {"FAT32"};
+       char* volumeLabel = {"FREERDP"};  /* TODO: Add sub routine to correctly pick up Volume Label name for each O/S supported */
+       chardiskType = {"FAT32"};
        char* outStr;
        size_t len;
 
@@ -581,12 +591,14 @@ static void disk_process_irp_list(DISK_DEVICE* disk)
 
        while (1)
        {
-               if (freerdp_thread_is_stopped(disk->thread))
+               if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0)
                        break;
 
-               freerdp_thread_lock(disk->thread);
-               irp = (IRP*)list_dequeue(disk->irp_list);
-               freerdp_thread_unlock(disk->thread);
+               WaitForSingleObject(disk->mutex, INFINITE);
+
+               irp = (IRP*) list_dequeue(disk->irp_list);
+
+               ReleaseMutex(disk->mutex);
 
                if (irp == NULL)
                        break;
@@ -597,63 +609,65 @@ static void disk_process_irp_list(DISK_DEVICE* disk)
 
 static void* disk_thread_func(void* arg)
 {
-       DISK_DEVICE* disk = (DISK_DEVICE*)arg;
+       DISK_DEVICE* disk = (DISK_DEVICE*) arg;
 
        while (1)
        {
-               freerdp_thread_wait(disk->thread);
+               WaitForSingleObject(disk->irpEvent, INFINITE);
 
-               if (freerdp_thread_is_stopped(disk->thread))
+               if (WaitForSingleObject(disk->stopEvent, 0) == WAIT_OBJECT_0)
                        break;
 
-               freerdp_thread_reset(disk->thread);
+               ResetEvent(disk->irpEvent);
                disk_process_irp_list(disk);
        }
 
-       freerdp_thread_quit(disk->thread);
-
        return NULL;
 }
 
 static void disk_irp_request(DEVICE* device, IRP* irp)
 {
-       DISK_DEVICE* disk = (DISK_DEVICE*)device;
+       DISK_DEVICE* disk = (DISK_DEVICE*) device;
 
-       freerdp_thread_lock(disk->thread);
+       WaitForSingleObject(disk->mutex, INFINITE);
        list_enqueue(disk->irp_list, irp);
-       freerdp_thread_unlock(disk->thread);
+       ReleaseMutex(disk->mutex);
 
-       freerdp_thread_signal(disk->thread);
+       SetEvent(disk->irpEvent);
 }
 
 static void disk_free(DEVICE* device)
 {
-       DISK_DEVICE* disk = (DISK_DEVICE*)device;
        IRP* irp;
        DISK_FILE* file;
+       DISK_DEVICE* disk = (DISK_DEVICE*) device;
 
-       freerdp_thread_stop(disk->thread);
-       freerdp_thread_free(disk->thread);
+       SetEvent(disk->stopEvent);
+       CloseHandle(disk->thread);
+       CloseHandle(disk->irpEvent);
+       CloseHandle(disk->mutex);
 
-       while ((irp = (IRP*)list_dequeue(disk->irp_list)) != NULL)
+       while ((irp = (IRP*) list_dequeue(disk->irp_list)) != NULL)
                irp->Discard(irp);
+
        list_free(disk->irp_list);
 
-       while ((file = (DISK_FILE*)list_dequeue(disk->files)) != NULL)
+       while ((file = (DISK_FILE*) list_dequeue(disk->files)) != NULL)
                disk_file_free(file);
+
        list_free(disk->files);
        xfree(disk);
 }
 
 int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
 {
-       DISK_DEVICE* disk;
        char* name;
        char* path;
        int i, len;
+       DISK_DEVICE* disk;
 
-       name = (char*)pEntryPoints->plugin_data->data[1];
-       path = (char*)pEntryPoints->plugin_data->data[2];
+       name = (char*) pEntryPoints->plugin_data->data[1];
+       path = (char*) pEntryPoints->plugin_data->data[2];
 
        if (name[0] && path[0])
        {
@@ -666,6 +680,7 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
 
                len = strlen(name);
                disk->device.data = stream_new(len + 1);
+
                for (i = 0; i <= len; i++)
                        stream_write_uint8(disk->device.data, name[i] < 0 ? '_' : name[i]);
 
@@ -673,11 +688,14 @@ int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
                disk->files = list_new();
 
                disk->irp_list = list_new();
-               disk->thread = freerdp_thread_new();
+               disk->mutex = CreateMutex(NULL, FALSE, NULL);
+               disk->irpEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+               disk->stopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+               disk->thread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) disk_thread_func, disk, CREATE_SUSPENDED, NULL);
 
-               pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)disk);
+               pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*) disk);
 
-               freerdp_thread_start(disk->thread, disk_thread_func, disk);
+               ResumeThread(disk->thread);
        }
 
        return 0;
index c7fcbb0..8c03594 100644 (file)
@@ -235,11 +235,11 @@ static boolean rdpdr_process_irp(rdpdrPlugin* rdpdr, STREAM* data_in)
 
 static void rdpdr_process_receive(rdpSvcPlugin* plugin, STREAM* data_in)
 {
-       rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin;
        uint16 component;
        uint16 packetID;
        uint32 deviceID;
        uint32 status;
+       rdpdrPlugin* rdpdr = (rdpdrPlugin*) plugin;
 
        stream_read_uint16(data_in, component);
        stream_read_uint16(data_in, packetID);
index c3ba985..cac1967 100644 (file)
 
 #include "scard_main.h"
 
-static void
-scard_free(DEVICE* dev)
+static void scard_free(DEVICE* dev)
 {
-       SCARD_DEVICE* scard = (SCARD_DEVICE*)dev;
        IRP* irp;
        COMPLETIONIDINFO* CompletionIdInfo;
+       SCARD_DEVICE* scard = (SCARD_DEVICE*) dev;
 
        freerdp_thread_stop(scard->thread);
        freerdp_thread_free(scard->thread);
        
-       while ((irp = (IRP*)list_dequeue(scard->irp_list)) != NULL)
+       while ((irp = (IRP*) list_dequeue(scard->irp_list)) != NULL)
                irp->Discard(irp);
+
        list_free(scard->irp_list);
 
        /* Begin TS Client defect workaround. */
-       while ((CompletionIdInfo = (COMPLETIONIDINFO*)list_dequeue(scard->CompletionIds)) != NULL)
+
+       while ((CompletionIdInfo = (COMPLETIONIDINFO*) list_dequeue(scard->CompletionIds)) != NULL)
                xfree(CompletionIdInfo);
+
        list_free(scard->CompletionIds);
+
        /* End TS Client defect workaround. */
 
        xfree(dev);
        return;
 }
 
-
-static void
-scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
+static void scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
 {
        switch (irp->MajorFunction)
        {
@@ -80,16 +81,14 @@ scard_process_irp(SCARD_DEVICE* scard, IRP* irp)
        }
 }
 
-
-static void
-scard_process_irp_list(SCARD_DEVICE* scard)
+static void scard_process_irp_list(SCARD_DEVICE* scard)
 {
-       IRP *irp;
+       IRPirp;
 
        while (!freerdp_thread_is_stopped(scard->thread))
        {
                freerdp_thread_lock(scard->thread);
-               irp = (IRP *) list_dequeue(scard->irp_list);
+               irp = (IRP*) list_dequeue(scard->irp_list);
                freerdp_thread_unlock(scard->thread);
 
                if (irp == NULL)
@@ -99,16 +98,14 @@ scard_process_irp_list(SCARD_DEVICE* scard)
        }
 }
 
-
-struct scard_irp_thread_args {
+struct scard_irp_thread_args
+{
        SCARD_DEVICE* scard;
        IRP* irp;
        freerdp_thread* thread;
 };
  
-
-static void
-scard_process_irp_thread_func(struct scard_irp_thread_args* args)
+static void scard_process_irp_thread_func(struct scard_irp_thread_args* args)
 {
        scard_process_irp(args->scard, args->irp);
 
@@ -116,9 +113,7 @@ scard_process_irp_thread_func(struct scard_irp_thread_args* args)
        xfree(args);
 }
 
-
-static void *
-scard_thread_func(void* arg)
+static void* scard_thread_func(void* arg)
 {
        SCARD_DEVICE* scard = (SCARD_DEVICE*) arg;
 
@@ -138,16 +133,14 @@ scard_thread_func(void* arg)
        return NULL;
 }
 
-
 /* Begin TS Client defect workaround. */
-static COMPLETIONIDINFO* 
-scard_mark_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
+static COMPLETIONIDINFO* scard_mark_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
 {
-/* 
- * Search from the beginning of the LIST for one outstanding "CompletionID" 
- * that matches the one passed in.  If there is one, mark it as a duplicate
- * if it is not already marked. 
- */
+       /*
+        * Search from the beginning of the LIST for one outstanding "CompletionID"
       * that matches the one passed in.  If there is one, mark it as a duplicate
+        * if it is not already marked.
       */
        LIST_ITEM* item;
        COMPLETIONIDINFO* CompletionIdInfo;
 
@@ -164,18 +157,18 @@ scard_mark_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
                        return CompletionIdInfo;
                }
        }
+
        return NULL;    /* Either no items in the list or no match. */
 }
 
-static boolean 
-scard_check_for_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
+static boolean  scard_check_for_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
 {
-/* 
- * Search from the end of the LIST for one outstanding "CompletionID" 
- * that matches the one passed in.  Remove it from the list and free the 
- * memory associated with it.  Return whether or not it was marked 
- * as a duplicate.
- */
+       /*
+        * Search from the end of the LIST for one outstanding "CompletionID"
+        * that matches the one passed in.  Remove it from the list and free the
+        * memory associated with it.  Return whether or not it was marked
       * as a duplicate.
       */
        LIST_ITEM* item;
        COMPLETIONIDINFO* CompletionIdInfo;
        boolean duplicate;
@@ -195,21 +188,22 @@ scard_check_for_duplicate_id(SCARD_DEVICE* scard, uint32 CompletionId)
                        return duplicate;
                }
        }
+
        /* This function should only be called when there is
         * at least one outstanding CompletionID item in the list.
         */
        DEBUG_WARN("Error!!! No CompletionIDs (or no matching IDs) in the list!");
+
        return false;
 }
 
-static void 
-scard_irp_complete(IRP* irp)
+static void  scard_irp_complete(IRP* irp)
 {
-/* This function is (mostly) a copy of the statically-declared "irp_complete()" 
- * function except that this function adds extra operations for the 
- * smart card's handling of duplicate "CompletionID"s.  This function needs 
- * to be in this file so that "scard_irp_request()" can reference it.
- */
+       /* This function is (mostly) a copy of the statically-declared "irp_complete()"
+        * function except that this function adds extra operations for the
+        * smart card's handling of duplicate "CompletionID"s.  This function needs
       * to be in this file so that "scard_irp_request()" can reference it.
       */
        int pos;
        boolean duplicate;
        SCARD_DEVICE* scard = (SCARD_DEVICE*)irp->device;
@@ -247,13 +241,10 @@ scard_irp_complete(IRP* irp)
 }
 /* End TS Client defect workaround. */
 
-
-static void
-scard_irp_request(DEVICE* device, IRP* irp)
+static void scard_irp_request(DEVICE* device, IRP* irp)
 {
        COMPLETIONIDINFO* CompletionIdInfo;
-
-       SCARD_DEVICE* scard = (SCARD_DEVICE*)device;
+       SCARD_DEVICE* scard = (SCARD_DEVICE*) device;
 
        /* Begin TS Client defect workaround. */
        CompletionIdInfo= xnew(COMPLETIONIDINFO);
index 6d06095..0506c2b 100644 (file)
@@ -110,9 +110,11 @@ static rdpSvcPlugin* svc_plugin_find_by_open_handle(uint32 open_handle)
        rdpSvcPlugin * plugin;
 
        WaitForSingleObject(g_mutex, INFINITE);
+
        for (list = g_svc_plugin_list; list; list = list->next)
        {
                plugin = list->plugin;
+
                if (plugin->priv->open_handle == open_handle)
                {
                        ReleaseMutex(g_mutex);
@@ -120,6 +122,7 @@ static rdpSvcPlugin* svc_plugin_find_by_open_handle(uint32 open_handle)
                }
        }
        ReleaseMutex(g_mutex);
+
        return NULL;
 }
 
@@ -215,22 +218,26 @@ static void svc_plugin_open_event(uint32 openHandle, uint32 event, void* pData,
        DEBUG_SVC("openHandle %d event %d dataLength %d totalLength %d dataFlags %d",
                openHandle, event, dataLength, totalLength, dataFlags);
 
-       plugin = (rdpSvcPlugin*)svc_plugin_find_by_open_handle(openHandle);
+       plugin = (rdpSvcPlugin*) svc_plugin_find_by_open_handle(openHandle);
+
        if (plugin == NULL)
        {
                printf("svc_plugin_open_event: error no match\n");
                return;
        }
+
        switch (event)
        {
                case CHANNEL_EVENT_DATA_RECEIVED:
                        svc_plugin_process_received(plugin, pData, dataLength, totalLength, dataFlags);
                        break;
+
                case CHANNEL_EVENT_WRITE_COMPLETE:
-                       stream_free((STREAM*)pData);
+                       stream_free((STREAM*) pData);
                        break;
+
                case CHANNEL_EVENT_USER:
-                       svc_plugin_process_event(plugin, (RDP_EVENT*)pData);
+                       svc_plugin_process_event(plugin, (RDP_EVENT*) pData);
                        break;
        }
 }
@@ -347,19 +354,23 @@ static void svc_plugin_init_event(void* pInitHandle, uint32 event, void* pData,
 
        DEBUG_SVC("event %d", event);
 
-       plugin = (rdpSvcPlugin*)svc_plugin_find_by_init_handle(pInitHandle);
-       if (plugin == NULL)
+       plugin = (rdpSvcPlugin*) svc_plugin_find_by_init_handle(pInitHandle);
+
+       if (!plugin)
        {
                printf("svc_plugin_init_event: error no match\n");
                return;
        }
+
        switch (event)
        {
                case CHANNEL_EVENT_CONNECTED:
                        svc_plugin_process_connected(plugin, pData, dataLength);
                        break;
+
                case CHANNEL_EVENT_DISCONNECTED:
                        break;
+
                case CHANNEL_EVENT_TERMINATED:
                        svc_plugin_process_terminated(plugin);
                        break;
@@ -402,6 +413,7 @@ int svc_plugin_send(rdpSvcPlugin* plugin, STREAM* data_out)
 
        error = plugin->channel_entry_points.pVirtualChannelWrite(plugin->priv->open_handle,
                stream_get_data(data_out), stream_get_length(data_out), data_out);
+
        if (error != CHANNEL_RC_OK)
        {
                stream_free(data_out);
index c8ef1a7..3f1a0da 100644 (file)
@@ -85,6 +85,16 @@ WINPR_API HANDLE OpenEventW(DWORD dwDesiredAccess, BOOL bInheritHandle, LPCWSTR
 WINPR_API BOOL SetEvent(HANDLE hEvent);
 WINPR_API BOOL ResetEvent(HANDLE hEvent);
 
+#ifdef UNICODE
+#define CreateEvent            CreateEventW
+#define CreateEventEx          CreateEventExW
+#define OpenEvent              OpenEventW
+#else
+#define CreateEvent            CreateEventA
+#define CreateEventEx          CreateEventExA
+#define OpenEvent              OpenEventA
+#endif
+
 /* One-Time Initialization */
 
 typedef union _RTL_RUN_ONCE
index 1db26fe..7ecc6ec 100644 (file)
@@ -114,12 +114,15 @@ WINPR_API BOOL TerminateProcess(HANDLE hProcess, UINT uExitCode);
 
 /* Thread */
 
-WINPR_API HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
-               LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId);
+#define CREATE_SUSPENDED                               0x00000004
+#define STACK_SIZE_PARAM_IS_A_RESERVATION              0x00010000
 
 WINPR_API HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
        LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
 
+WINPR_API HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
+               LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId);
+
 WINPR_API VOID ExitThread(DWORD dwExitCode);
 
 WINPR_API HANDLE GetCurrentThread(VOID);
index 02e1c35..40e082c 100644 (file)
 
 #ifndef _WIN32
 
+#include <pthread.h>
+
+pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
+
 typedef struct _HANDLE_TABLE_ENTRY
 {
        ULONG Type;
@@ -49,33 +53,49 @@ void winpr_HandleTable_New()
 {
        size_t size;
 
-       HandleTable.Count = 0;
-       HandleTable.MaxCount = 64;
+       pthread_mutex_lock(&mutex);
 
-       size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount;
+       if (HandleTable.MaxCount < 1)
+       {
+               HandleTable.Count = 0;
+               HandleTable.MaxCount = 64;
+
+               size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount;
+
+               HandleTable.Entries = (PHANDLE_TABLE_ENTRY) malloc(size);
+               ZeroMemory(HandleTable.Entries, size);
+       }
 
-       HandleTable.Entries = (PHANDLE_TABLE_ENTRY) malloc(size);
-       ZeroMemory(HandleTable.Entries, size);
+       pthread_mutex_unlock(&mutex);
 }
 
 void winpr_HandleTable_Grow()
 {
        size_t size;
+
+       pthread_mutex_lock(&mutex);
+
        HandleTable.MaxCount *= 2;
 
        size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount;
 
        HandleTable.Entries = (PHANDLE_TABLE_ENTRY) realloc(HandleTable.Entries, size);
        ZeroMemory((void*) &HandleTable.Entries[HandleTable.MaxCount / 2], size / 2);
+
+       pthread_mutex_unlock(&mutex);
 }
 
 void winpr_HandleTable_Free()
 {
+       pthread_mutex_lock(&mutex);
+
        HandleTable.Count = 0;
        HandleTable.MaxCount = 0;
 
        free(HandleTable.Entries);
        HandleTable.Entries = NULL;
+
+       pthread_mutex_unlock(&mutex);
 }
 
 HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object)
@@ -84,6 +104,8 @@ HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object)
 
        HandleTable_GetInstance();
 
+       pthread_mutex_lock(&mutex);
+
        for (index = 0; index < (int) HandleTable.MaxCount; index++)
        {
                if (HandleTable.Entries[index].Object == NULL)
@@ -93,10 +115,14 @@ HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object)
                        HandleTable.Entries[index].Type = Type;
                        HandleTable.Entries[index].Object = Object;
 
+                       pthread_mutex_unlock(&mutex);
+
                        return Object;
                }
        }
 
+       pthread_mutex_unlock(&mutex);
+
        /* no available entry was found, the table needs to be grown */
 
        winpr_HandleTable_Grow();
@@ -112,6 +138,8 @@ BOOL winpr_Handle_Remove(HANDLE handle)
 
        HandleTable_GetInstance();
 
+       pthread_mutex_lock(&mutex);
+
        for (index = 0; index < (int) HandleTable.MaxCount; index++)
        {
                if (HandleTable.Entries[index].Object == handle)
@@ -120,10 +148,14 @@ BOOL winpr_Handle_Remove(HANDLE handle)
                        HandleTable.Entries[index].Object = NULL;
                        HandleTable.Count--;
 
+                       pthread_mutex_unlock(&mutex);
+
                        return TRUE;
                }
        }
 
+       pthread_mutex_unlock(&mutex);
+
        return FALSE;
 }
 
@@ -133,12 +165,19 @@ ULONG winpr_Handle_GetType(HANDLE handle)
 
        HandleTable_GetInstance();
 
+       pthread_mutex_lock(&mutex);
+
        for (index = 0; index < (int) HandleTable.MaxCount; index++)
        {
                if (HandleTable.Entries[index].Object == handle)
+               {
+                       pthread_mutex_unlock(&mutex);
                        return HandleTable.Entries[index].Type;
+               }
        }
 
+       pthread_mutex_unlock(&mutex);
+
        return HANDLE_TYPE_NONE;
 }
 
@@ -155,16 +194,23 @@ BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject)
 
        HandleTable_GetInstance();
 
+       pthread_mutex_lock(&mutex);
+
        for (index = 0; index < (int) HandleTable.MaxCount; index++)
        {
                if (HandleTable.Entries[index].Object == handle)
                {
                        *pType = HandleTable.Entries[index].Type;
                        *pObject = HandleTable.Entries[index].Object;
+
+                       pthread_mutex_unlock(&mutex);
+
                        return TRUE;
                }
        }
 
+       pthread_mutex_unlock(&mutex);
+
        return FALSE;
 }
 
index d78fd13..5eddde9 100644 (file)
@@ -49,7 +49,7 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
 
        event = (WINPR_EVENT*) malloc(sizeof(WINPR_EVENT));
 
-       if (!event)
+       if (event)
        {
                event->bManualReset = bManualReset;
 
@@ -63,6 +63,7 @@ HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset,
 
                if (pipe(event->pipe_fd) < 0)
                {
+                       printf("CreateEventW: failed to create event\n");
                        return NULL;
                }
 
index 5a2707c..58aed1e 100644 (file)
@@ -74,7 +74,7 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
                FD_SET(event->pipe_fd[0], &rfds);
                ZeroMemory(&timeout, sizeof(timeout));
 
-               if (dwMilliseconds != INFINITE)
+               if ((dwMilliseconds != INFINITE) && (dwMilliseconds != 0))
                {
                        timeout.tv_usec = dwMilliseconds * 1000;
                }
index 45a7119..9ce746c 100644 (file)
@@ -67,6 +67,8 @@
 
 #ifndef _WIN32
 
+#include <winpr/crt.h>
+
 #include <pthread.h>
 
 /**
 
 typedef void *(*pthread_start_routine)(void*);
 
-HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
-               LPTHREAD_START_ROUTINE lpStartAddress,LPVOID lpParameter,DWORD dwCreationFlags,LPDWORD lpThreadId)
+struct winpr_thread
 {
-       return NULL;
+       BOOL started;
+       pthread_t thread;
+       SIZE_T dwStackSize;
+       LPVOID lpParameter;
+       pthread_mutex_t mutex;
+       LPTHREAD_START_ROUTINE lpStartAddress;
+       LPSECURITY_ATTRIBUTES lpThreadAttributes;
+};
+typedef struct winpr_thread WINPR_THREAD;
+
+void winpr_StartThread(WINPR_THREAD* thread)
+{
+       pthread_attr_t attr;
+
+       pthread_attr_init(&attr);
+       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+
+       if (thread->dwStackSize > 0)
+               pthread_attr_setstacksize(&attr, (size_t) thread->dwStackSize);
+
+       thread->started = TRUE;
+       pthread_create(&thread->thread, &attr, (pthread_start_routine) thread->lpStartAddress, thread->lpParameter);
+
+       pthread_attr_destroy(&attr);
 }
 
 HANDLE CreateThread(LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
        LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
 {
        HANDLE handle;
-       pthread_t thread;
-       pthread_attr_t attr;
+       WINPR_THREAD* thread;
 
-       pthread_attr_init(&attr);
-       pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
+       thread = (WINPR_THREAD*) malloc(sizeof(WINPR_THREAD));
+       ZeroMemory(thread, sizeof(WINPR_THREAD));
 
-       if (dwStackSize > 0)
-               pthread_attr_setstacksize(&attr, (size_t) dwStackSize);
+       thread->started = FALSE;
+       thread->dwStackSize = dwStackSize;
+       thread->lpParameter = lpParameter;
+       thread->lpStartAddress = lpStartAddress;
+       thread->lpThreadAttributes = lpThreadAttributes;
 
-       pthread_create(&thread, &attr, (pthread_start_routine) lpStartAddress, lpParameter);
+       pthread_mutex_init(&thread->mutex, 0);
 
        handle = winpr_Handle_Insert(HANDLE_TYPE_THREAD, (void*) thread);
 
-       pthread_attr_destroy(&attr);
+       if (!(dwCreationFlags & CREATE_SUSPENDED))
+               winpr_StartThread(thread);
 
        return handle;
 }
 
-VOID ExitThread(DWORD dwExitCode)
+HANDLE CreateRemoteThread(HANDLE hProcess, LPSECURITY_ATTRIBUTES lpThreadAttributes, SIZE_T dwStackSize,
+               LPTHREAD_START_ROUTINE lpStartAddress, LPVOID lpParameter, DWORD dwCreationFlags, LPDWORD lpThreadId)
 {
+       return NULL;
+}
 
+VOID ExitThread(DWORD dwExitCode)
+{
+       pthread_exit((void*) dwExitCode);
 }
 
 HANDLE GetCurrentThread(VOID)
@@ -121,6 +154,22 @@ DWORD GetCurrentThreadId(VOID)
 
 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;
 }
 
@@ -136,6 +185,21 @@ BOOL SwitchToThread(VOID)
 
 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;
 }