Revert "winpr-handle: removed RegisterHandleCloseCb() which would require a better synchronization"

RegisterHandleCloseCb() is also useful to don't get a circular dependency, a better synchronization must be find out...

This reverts commit 8f3b3fa573.
This commit is contained in:
Emmanuel Ledoux 2014-07-02 16:57:20 +02:00 committed by Emmanuel Ledoux
parent 8f3b3fa573
commit db1fba3a68
4 changed files with 112 additions and 4 deletions

View File

@ -70,6 +70,7 @@ typedef struct comm_device COMM_DEVICE;
static COMM_DEVICE **_CommDevices = NULL;
static HANDLE_CREATOR *_CommHandleCreator = NULL;
static HANDLE_CLOSE_CB *_CommHandleCloseCb = NULL;
static pthread_once_t _CommInitialized = PTHREAD_ONCE_INIT;
static void _CommInit()
@ -79,6 +80,7 @@ static void _CommInit()
assert(_Log == NULL);
assert(_CommDevices == NULL);
assert(_CommHandleCreator == NULL);
assert(_CommHandleCloseCb == NULL);
_Log = WLog_Get("com.winpr.comm");
@ -93,9 +95,19 @@ static void _CommInit()
RegisterHandleCreator(_CommHandleCreator);
}
_CommHandleCloseCb = (HANDLE_CLOSE_CB*)malloc(sizeof(HANDLE_CLOSE_CB));
if (_CommHandleCloseCb)
{
_CommHandleCloseCb->IsHandled = CommIsHandled;
_CommHandleCloseCb->CloseHandle = CommCloseHandle;
RegisterHandleCloseCb(_CommHandleCloseCb);
}
assert(_Log != NULL);
assert(_CommDevices != NULL);
assert(_CommHandleCreator != NULL);
assert(_CommHandleCloseCb != NULL);
}
@ -1403,6 +1415,25 @@ HANDLE CommCreateFileA(LPCSTR lpDeviceName, DWORD dwDesiredAccess, DWORD dwShare
}
BOOL CommIsHandled(HANDLE handle)
{
WINPR_COMM *pComm;
if (!CommInitialized())
return FALSE;
pComm = (WINPR_COMM*)handle;
if (!pComm || pComm->Type != HANDLE_TYPE_COMM)
{
SetLastError(ERROR_INVALID_HANDLE);
return FALSE;
}
return TRUE;
}
BOOL CommCloseHandle(HANDLE handle)
{
WINPR_COMM *pComm;

View File

@ -89,6 +89,7 @@ typedef struct winpr_comm WINPR_COMM;
void CommLog_Print(int wlog_level, char *fmt, ...);
BOOL CommIsHandled(HANDLE handle);
BOOL CommCloseHandle(HANDLE handle);
#endif /* _WIN32 */

View File

@ -42,14 +42,82 @@
#include "../handle/handle.h"
/* _HandleCreators is a NULL-terminated array with a maximun of HANDLE_CREATOR_MAX HANDLE_CREATOR */
#define HANDLE_CLOSE_CB_MAX 128
static HANDLE_CLOSE_CB **_HandleCloseCbs = NULL;
static pthread_once_t _HandleCloseCbsInitialized = PTHREAD_ONCE_INIT;
static void _HandleCloseCbsInit()
{
/* NB: error management to be done outside of this function */
assert(_HandleCloseCbs == NULL);
_HandleCloseCbs = (HANDLE_CLOSE_CB**)calloc(HANDLE_CLOSE_CB_MAX+1, sizeof(HANDLE_CLOSE_CB*));
assert(_HandleCloseCbs != NULL);
}
/**
* Returns TRUE on success, FALSE otherwise.
*/
BOOL RegisterHandleCloseCb(HANDLE_CLOSE_CB *pHandleCloseCb)
{
int i;
if (pthread_once(&_HandleCloseCbsInitialized, _HandleCloseCbsInit) != 0)
{
return FALSE;
}
if (_HandleCloseCbs == NULL)
{
return FALSE;
}
for (i=0; i<HANDLE_CLOSE_CB_MAX; i++)
{
if (_HandleCloseCbs[i] == NULL)
{
_HandleCloseCbs[i] = pHandleCloseCb;
return TRUE;
}
}
return FALSE;
}
BOOL CloseHandle(HANDLE hObject)
{
int i;
ULONG Type;
PVOID Object;
if (!winpr_Handle_GetInfo(hObject, &Type, &Object))
return FALSE;
if (pthread_once(&_HandleCloseCbsInitialized, _HandleCloseCbsInit) != 0)
{
return FALSE;
}
if (_HandleCloseCbs == NULL)
{
return FALSE;
}
for (i=0; _HandleCloseCbs[i] != NULL; i++)
{
HANDLE_CLOSE_CB *close_cb = (HANDLE_CLOSE_CB*)_HandleCloseCbs[i];
if (close_cb && close_cb->IsHandled(hObject))
{
return close_cb->CloseHandle(hObject);
}
}
if (Type == HANDLE_TYPE_THREAD)
{
@ -207,10 +275,6 @@ BOOL CloseHandle(HANDLE hObject)
return TRUE;
}
else if (Type == HANDLE_TYPE_COMM)
{
return CommCloseHandle(hObject);
}
return FALSE;
}

View File

@ -65,4 +65,16 @@ static inline BOOL winpr_Handle_GetInfo(HANDLE handle, ULONG* pType, PVOID* pObj
return TRUE;
}
typedef BOOL (*pcIsHandled)(HANDLE handle);
typedef BOOL (*pcCloseHandle)(HANDLE handle);
typedef struct _HANDLE_CLOSE_CB
{
pcIsHandled IsHandled;
pcCloseHandle CloseHandle;
} HANDLE_CLOSE_CB;
BOOL RegisterHandleCloseCb(HANDLE_CLOSE_CB *pHandleClose);
#endif /* WINPR_HANDLE_PRIVATE_H */