winpr: unify handle types

This commit is contained in:
Marc-André Moreau 2013-05-16 17:32:58 -04:00
parent d99c8b8dc2
commit 72e9087d1f
16 changed files with 246 additions and 109 deletions

View File

@ -27,26 +27,10 @@
#include <winpr/wtypes.h>
#include <winpr/security.h>
#define HANDLE_TYPE_NONE 0
#define HANDLE_TYPE_THREAD 1
#define HANDLE_TYPE_EVENT 2
#define HANDLE_TYPE_MUTEX 3
#define HANDLE_TYPE_SEMAPHORE 4
#define HANDLE_TYPE_TIMER 5
#define HANDLE_TYPE_NAMED_PIPE 6
#define HANDLE_TYPE_ANONYMOUS_PIPE 7
#ifdef __cplusplus
extern "C" {
#endif
WINPR_API HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object);
WINPR_API BOOL winpr_Handle_Remove(HANDLE handle);
WINPR_API ULONG winpr_Handle_GetType(HANDLE handle);
WINPR_API PVOID winpr_Handle_GetObject(HANDLE handle);
WINPR_API BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject);
#ifndef _WIN32
#define HANDLE_FLAG_INHERIT 0x00000001

View File

@ -139,6 +139,10 @@
#include <sys/statvfs.h>
#endif
#include "../handle/handle.h"
#include "../pipe/pipe.h"
HANDLE CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, LPSECURITY_ATTRIBUTES lpSecurityAttributes,
DWORD dwCreationDisposition, DWORD dwFlagsAndAttributes, HANDLE hTemplateFile)
{
@ -166,6 +170,7 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
{
ULONG Type;
PVOID Object;
WINPR_PIPE* pipe;
if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
return FALSE;
@ -173,11 +178,10 @@ BOOL ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead,
if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
{
int status;
int read_fd;
read_fd = (int) ((ULONG_PTR) Object);
pipe = (WINPR_PIPE*) Object;
status = read(read_fd, lpBuffer, nNumberOfBytesToRead);
status = read(pipe->fd, lpBuffer, nNumberOfBytesToRead);
*lpNumberOfBytesRead = status;
@ -204,6 +208,7 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
{
ULONG Type;
PVOID Object;
WINPR_PIPE* pipe;
if (!winpr_Handle_GetInfo(hFile, &Type, &Object))
return FALSE;
@ -211,11 +216,10 @@ BOOL WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite,
if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
{
int status;
int write_fd;
write_fd = (int) ((ULONG_PTR) Object);
pipe = (WINPR_PIPE*) Object;
status = write(write_fd, lpBuffer, nNumberOfBytesToWrite);
status = write(pipe->fd, lpBuffer, nNumberOfBytesToWrite);
*lpNumberOfBytesWritten = status;

View File

@ -20,6 +20,7 @@ set(MODULE_PREFIX "WINPR_HANDLE")
set(${MODULE_PREFIX}_SRCS
handle.c
handle.h
table.c)
if(MSVC AND (NOT MONOLITHIC_BUILD))

View File

@ -27,11 +27,14 @@
#include "../synch/synch.h"
#include "../thread/thread.h"
#include "../pipe/pipe.h"
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include "../handle/handle.h"
BOOL CloseHandle(HANDLE hObject)
{
ULONG Type;
@ -52,7 +55,11 @@ BOOL CloseHandle(HANDLE hObject)
}
else if (Type == HANDLE_TYPE_MUTEX)
{
pthread_mutex_destroy((pthread_mutex_t*) Object);
WINPR_MUTEX* mutex;
mutex = (WINPR_MUTEX*) Object;
pthread_mutex_destroy(&mutex->mutex);
winpr_Handle_Remove(Object);
free(Object);
@ -119,13 +126,13 @@ BOOL CloseHandle(HANDLE hObject)
}
else if (Type == HANDLE_TYPE_ANONYMOUS_PIPE)
{
int pipe_fd;
WINPR_PIPE* pipe;
pipe_fd = (int) ((ULONG_PTR) Object);
pipe = (WINPR_PIPE*) Object;
if (pipe_fd != -1)
if (pipe->fd != -1)
{
close(pipe_fd);
close(pipe->fd);
}
winpr_Handle_Remove(Object);

View File

@ -0,0 +1,66 @@
/**
* WinPR: Windows Portable Runtime
* Handle Management
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WINPR_HANDLE_PRIVATE_H
#define WINPR_HANDLE_PRIVATE_H
#include <pthread.h>
#include <winpr/handle.h>
#define HANDLE_TYPE_NONE 0
#define HANDLE_TYPE_THREAD 1
#define HANDLE_TYPE_EVENT 2
#define HANDLE_TYPE_MUTEX 3
#define HANDLE_TYPE_SEMAPHORE 4
#define HANDLE_TYPE_TIMER 5
#define HANDLE_TYPE_NAMED_PIPE 6
#define HANDLE_TYPE_ANONYMOUS_PIPE 7
typedef struct _HANDLE_TABLE_ENTRY
{
ULONG Type;
PVOID Object;
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
typedef struct _HANDLE_TABLE
{
LONG Count;
LONG MaxCount;
PHANDLE_TABLE_ENTRY Entries;
} HANDLE_TABLE, *PHANDLE_TABLE;
#define WINPR_HANDLE_DEF() \
void* handle
#define HandleTable_GetInstance() \
if (g_WinPR_HandleTable.MaxCount < 1) \
winpr_HandleTable_New()
extern HANDLE_TABLE g_WinPR_HandleTable;
extern pthread_mutex_t g_WinPR_HandleTable_Mutex;
WINPR_API HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object);
WINPR_API BOOL winpr_Handle_Remove(HANDLE handle);
WINPR_API ULONG winpr_Handle_GetType(HANDLE handle);
WINPR_API PVOID winpr_Handle_GetObject(HANDLE handle);
WINPR_API BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject);
#endif /* WINPR_HANDLE_PRIVATE_H */

View File

@ -28,74 +28,58 @@
#include <pthread.h>
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
#include "../handle/handle.h"
typedef struct _HANDLE_TABLE_ENTRY
{
ULONG Type;
PVOID Object;
} HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;
typedef struct _HANDLE_TABLE
{
LONG Count;
LONG MaxCount;
PHANDLE_TABLE_ENTRY Entries;
} HANDLE_TABLE, *PHANDLE_TABLE;
static HANDLE_TABLE HandleTable = { 0, 0, NULL };
#define HandleTable_GetInstance() \
if (HandleTable.MaxCount < 1) \
winpr_HandleTable_New()
HANDLE_TABLE g_WinPR_HandleTable = { 0, 0, NULL };
pthread_mutex_t g_WinPR_HandleTable_Mutex = PTHREAD_MUTEX_INITIALIZER;
void winpr_HandleTable_New()
{
size_t size;
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&g_WinPR_HandleTable_Mutex);
if (HandleTable.MaxCount < 1)
if (g_WinPR_HandleTable.MaxCount < 1)
{
HandleTable.Count = 0;
HandleTable.MaxCount = 64;
g_WinPR_HandleTable.Count = 0;
g_WinPR_HandleTable.MaxCount = 64;
size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount;
size = sizeof(HANDLE_TABLE_ENTRY) * g_WinPR_HandleTable.MaxCount;
HandleTable.Entries = (PHANDLE_TABLE_ENTRY) malloc(size);
ZeroMemory(HandleTable.Entries, size);
g_WinPR_HandleTable.Entries = (PHANDLE_TABLE_ENTRY) malloc(size);
ZeroMemory(g_WinPR_HandleTable.Entries, size);
}
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
}
void winpr_HandleTable_Grow()
{
size_t size;
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&g_WinPR_HandleTable_Mutex);
HandleTable.MaxCount *= 2;
g_WinPR_HandleTable.MaxCount *= 2;
size = sizeof(HANDLE_TABLE_ENTRY) * HandleTable.MaxCount;
size = sizeof(HANDLE_TABLE_ENTRY) * g_WinPR_HandleTable.MaxCount;
HandleTable.Entries = (PHANDLE_TABLE_ENTRY) realloc(HandleTable.Entries, size);
ZeroMemory((void*) &HandleTable.Entries[HandleTable.MaxCount / 2], size / 2);
g_WinPR_HandleTable.Entries = (PHANDLE_TABLE_ENTRY) realloc(g_WinPR_HandleTable.Entries, size);
ZeroMemory((void*) &g_WinPR_HandleTable.Entries[g_WinPR_HandleTable.MaxCount / 2], size / 2);
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
}
void winpr_HandleTable_Free()
{
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&g_WinPR_HandleTable_Mutex);
HandleTable.Count = 0;
HandleTable.MaxCount = 0;
g_WinPR_HandleTable.Count = 0;
g_WinPR_HandleTable.MaxCount = 0;
free(HandleTable.Entries);
HandleTable.Entries = NULL;
free(g_WinPR_HandleTable.Entries);
g_WinPR_HandleTable.Entries = NULL;
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
}
HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object)
@ -104,24 +88,24 @@ HANDLE winpr_Handle_Insert(ULONG Type, PVOID Object)
HandleTable_GetInstance();
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&g_WinPR_HandleTable_Mutex);
for (index = 0; index < (int) HandleTable.MaxCount; index++)
for (index = 0; index < (int) g_WinPR_HandleTable.MaxCount; index++)
{
if (HandleTable.Entries[index].Object == NULL)
if (g_WinPR_HandleTable.Entries[index].Object == NULL)
{
HandleTable.Count++;
g_WinPR_HandleTable.Count++;
HandleTable.Entries[index].Type = Type;
HandleTable.Entries[index].Object = Object;
g_WinPR_HandleTable.Entries[index].Type = Type;
g_WinPR_HandleTable.Entries[index].Object = Object;
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
return Object;
}
}
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
/* no available entry was found, the table needs to be grown */
@ -138,23 +122,23 @@ BOOL winpr_Handle_Remove(HANDLE handle)
HandleTable_GetInstance();
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&g_WinPR_HandleTable_Mutex);
for (index = 0; index < (int) HandleTable.MaxCount; index++)
for (index = 0; index < (int) g_WinPR_HandleTable.MaxCount; index++)
{
if (HandleTable.Entries[index].Object == handle)
if (g_WinPR_HandleTable.Entries[index].Object == handle)
{
HandleTable.Entries[index].Type = HANDLE_TYPE_NONE;
HandleTable.Entries[index].Object = NULL;
HandleTable.Count--;
g_WinPR_HandleTable.Entries[index].Type = HANDLE_TYPE_NONE;
g_WinPR_HandleTable.Entries[index].Object = NULL;
g_WinPR_HandleTable.Count--;
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
return TRUE;
}
}
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
return FALSE;
}
@ -165,18 +149,18 @@ ULONG winpr_Handle_GetType(HANDLE handle)
HandleTable_GetInstance();
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&g_WinPR_HandleTable_Mutex);
for (index = 0; index < (int) HandleTable.MaxCount; index++)
for (index = 0; index < (int) g_WinPR_HandleTable.MaxCount; index++)
{
if (HandleTable.Entries[index].Object == handle)
if (g_WinPR_HandleTable.Entries[index].Object == handle)
{
pthread_mutex_unlock(&mutex);
return HandleTable.Entries[index].Type;
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
return g_WinPR_HandleTable.Entries[index].Type;
}
}
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
return HANDLE_TYPE_NONE;
}
@ -194,22 +178,22 @@ BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObject)
HandleTable_GetInstance();
pthread_mutex_lock(&mutex);
pthread_mutex_lock(&g_WinPR_HandleTable_Mutex);
for (index = 0; index < (int) HandleTable.MaxCount; index++)
for (index = 0; index < (int) g_WinPR_HandleTable.MaxCount; index++)
{
if (HandleTable.Entries[index].Object == handle)
if (g_WinPR_HandleTable.Entries[index].Object == handle)
{
*pType = HandleTable.Entries[index].Type;
*pObject = HandleTable.Entries[index].Object;
*pType = g_WinPR_HandleTable.Entries[index].Type;
*pObject = g_WinPR_HandleTable.Entries[index].Object;
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
return TRUE;
}
}
pthread_mutex_unlock(&mutex);
pthread_mutex_unlock(&g_WinPR_HandleTable_Mutex);
return FALSE;
}

View File

@ -19,7 +19,8 @@ set(MODULE_NAME "winpr-pipe")
set(MODULE_PREFIX "WINPR_PIPE")
set(${MODULE_PREFIX}_SRCS
pipe.c)
pipe.c
pipe.h)
if(MSVC AND (NOT MONOLITHIC_BUILD))
set(${MODULE_PREFIX}_SRCS ${${MODULE_PREFIX}_SRCS} module.def)

View File

@ -32,11 +32,17 @@
#ifndef _WIN32
#include "../handle/handle.h"
#include "pipe.h"
BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpPipeAttributes, DWORD nSize)
{
void* ptr;
HANDLE handle;
int pipe_fd[2];
WINPR_PIPE* pReadPipe;
WINPR_PIPE* pWritePipe;
pipe_fd[0] = -1;
pipe_fd[1] = -1;
@ -47,12 +53,19 @@ BOOL CreatePipe(PHANDLE hReadPipe, PHANDLE hWritePipe, LPSECURITY_ATTRIBUTES lpP
return FALSE;
}
ptr = (void*) ((ULONG_PTR) pipe_fd[0]);
handle = winpr_Handle_Insert(HANDLE_TYPE_ANONYMOUS_PIPE, ptr);
pReadPipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE));
pWritePipe = (WINPR_PIPE*) malloc(sizeof(WINPR_PIPE));
if (!pReadPipe || !pWritePipe)
return FALSE;
pReadPipe->fd = pipe_fd[0];
pWritePipe->fd = pipe_fd[1];
handle = winpr_Handle_Insert(HANDLE_TYPE_ANONYMOUS_PIPE, pReadPipe);
*((ULONG_PTR*) hReadPipe) = (ULONG_PTR) handle;
ptr = (void*) ((ULONG_PTR) pipe_fd[1]);
handle = winpr_Handle_Insert(HANDLE_TYPE_ANONYMOUS_PIPE, ptr);
handle = winpr_Handle_Insert(HANDLE_TYPE_ANONYMOUS_PIPE, pWritePipe);
*((ULONG_PTR*) hWritePipe) = (ULONG_PTR) handle;
return TRUE;

View File

@ -0,0 +1,41 @@
/**
* WinPR: Windows Portable Runtime
* Pipe Functions
*
* Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WINPR_PIPE_PRIVATE_H
#define WINPR_PIPE_PRIVATE_H
#ifndef _WIN32
#include <winpr/pipe.h>
#include "../handle/handle.h"
struct winpr_pipe
{
WINPR_HANDLE_DEF();
int fd;
};
typedef struct winpr_pipe WINPR_PIPE;
#endif
#endif /* WINPR_PIPE_PRIVATE_H */

View File

@ -40,6 +40,8 @@
#include <errno.h>
#endif
#include "../handle/handle.h"
CRITICAL_SECTION cs = { NULL, 0, 0, NULL, NULL, 0 };
HANDLE CreateEventW(LPSECURITY_ATTRIBUTES lpEventAttributes, BOOL bManualReset, BOOL bInitialState, LPCWSTR lpName)

View File

@ -37,19 +37,23 @@
#ifndef _WIN32
#include "../handle/handle.h"
HANDLE CreateMutexW(LPSECURITY_ATTRIBUTES lpMutexAttributes, BOOL bInitialOwner, LPCWSTR lpName)
{
HANDLE handle = NULL;
pthread_mutex_t* pMutex;
WINPR_MUTEX* mutex;
pMutex = (pthread_mutex_t*) malloc(sizeof(pthread_mutex_t));
mutex = (WINPR_MUTEX*) malloc(sizeof(WINPR_MUTEX));
if (pMutex)
if (mutex)
{
pthread_mutex_init(pMutex, 0);
handle = winpr_Handle_Insert(HANDLE_TYPE_MUTEX, pMutex);
pthread_mutex_init(&mutex->mutex, 0);
handle = winpr_Handle_Insert(HANDLE_TYPE_MUTEX, mutex);
if (bInitialOwner)
pthread_mutex_lock(pMutex);
pthread_mutex_lock(&mutex->mutex);
}
return handle;
@ -84,13 +88,15 @@ 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)
{
pthread_mutex_unlock((pthread_mutex_t*) Object);
mutex = (WINPR_MUTEX*) Object;
pthread_mutex_unlock(&mutex->mutex);
return TRUE;
}

View File

@ -31,6 +31,8 @@
#ifndef _WIN32
#include "../handle/handle.h"
HANDLE CreateSemaphoreW(LPSECURITY_ATTRIBUTES lpSemaphoreAttributes, LONG lInitialCount, LONG lMaximumCount, LPCWSTR lpName)
{
HANDLE handle;

View File

@ -24,6 +24,8 @@
#ifndef _WIN32
#include "../handle/handle.h"
#define WINPR_PIPE_SEMAPHORE 1
#if defined __APPLE__
@ -39,8 +41,18 @@
#define winpr_sem_t sem_t
#endif
struct winpr_mutex
{
WINPR_HANDLE_DEF();
pthread_mutex_t mutex;
};
typedef struct winpr_mutex WINPR_MUTEX;
struct winpr_semaphore
{
WINPR_HANDLE_DEF();
int pipe_fd[2];
winpr_sem_t* sem;
};
@ -48,6 +60,8 @@ typedef struct winpr_semaphore WINPR_SEMAPHORE;
struct winpr_event
{
WINPR_HANDLE_DEF();
int pipe_fd[2];
BOOL bAttached;
BOOL bManualReset;

View File

@ -41,6 +41,8 @@
#ifndef _WIN32
#include "../handle/handle.h"
DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
{
ULONG Type;
@ -70,10 +72,14 @@ DWORD WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
}
else if (Type == HANDLE_TYPE_MUTEX)
{
WINPR_MUTEX* mutex;
mutex = (WINPR_MUTEX*) Object;
if (dwMilliseconds != INFINITE)
fprintf(stderr, "WaitForSingleObject: timeout not implemented for mutex wait\n");
pthread_mutex_lock((pthread_mutex_t*) Object);
pthread_mutex_lock(&mutex->mutex);
}
else if (Type == HANDLE_TYPE_EVENT)
{

View File

@ -71,6 +71,8 @@
#include "thread.h"
#include "../handle/handle.h"
/**
* TODO: implement thread suspend/resume using pthreads
* http://stackoverflow.com/questions/3140867/suspend-pthreads-without-using-condition

View File

@ -22,14 +22,18 @@
#ifndef _WIN32
#include <pthread.h>
#include <winpr/thread.h>
#include <pthread.h>
#include "../handle/handle.h"
typedef void *(*pthread_start_routine)(void*);
struct winpr_thread
{
WINPR_HANDLE_DEF();
BOOL started;
DWORD dwExitCode;
pthread_t thread;