1
0
mirror of https://github.com/Ylianst/MeshAgent synced 2026-01-08 03:23:27 +00:00

Updated WriteEx

This commit is contained in:
Bryan Roe
2020-05-05 02:00:07 -07:00
parent a58c3279b7
commit 969909cca7
3 changed files with 88 additions and 2 deletions

View File

@@ -2819,6 +2819,33 @@ void ILibChain_AddWaitHandle(void *chain, HANDLE h, int msTIMEOUT, ILibChain_Wai
ILibForceUnBlockChain(chain); ILibForceUnBlockChain(chain);
} }
void __stdcall ILibChain_RemoveWaitHandle_APC(ULONG_PTR u)
{
ILibBaseChain *chain = (ILibBaseChain*)((void**)u)[0];
HANDLE h = (HANDLE)((void**)u)[1];
void *node = ILibLinkedList_GetNode_Search(chain->auxSelectHandles, NULL, h);
if (node != NULL)
{
//
// We found the HANDLE, so if we remove the HANDLE from the list, and
// set the unblock flag, we'll be good to go
//
ILibLinkedList_Remove(node);
chain->UnblockFlag = 1;
}
}
void ILibChain_RemoveWaitHandle(void *chain, HANDLE h)
{
//
// We must dispatch an APC to remove the wait handle,
// because we can't change the wait list during a WaitForMultipleObjectsEx() call
//
void **tmp = (void**)ILibMemory_SmartAllocate(2 * sizeof(void*));
tmp[0] = chain;
tmp[1] = h;
QueueUserAPC((PAPCFUNC)ILibChain_RemoveWaitHandle_APC, ILibChain_GetMicrostackThreadHandle(chain), (ULONG_PTR)tmp);
}
#endif #endif
/*! \fn ILibStartChain(void *Chain) /*! \fn ILibStartChain(void *Chain)

View File

@@ -974,6 +974,7 @@ int ILibIsRunningOnChainThread(void* chain);
char *ILibChain_GetMetaDataFromDescriptorSet(void *chain, fd_set *inr, fd_set *inw, fd_set *ine); char *ILibChain_GetMetaDataFromDescriptorSet(void *chain, fd_set *inr, fd_set *inw, fd_set *ine);
#ifdef WIN32 #ifdef WIN32
void ILibChain_AddWaitHandle(void *chain, HANDLE h, int msTIMEOUT, ILibChain_WaitHandleHandler handler, void *user); void ILibChain_AddWaitHandle(void *chain, HANDLE h, int msTIMEOUT, ILibChain_WaitHandleHandler handler, void *user);
void ILibChain_RemoveWaitHandle(void *chain, HANDLE h);
#define tv2LTtv1(ptv1, ptv2) ((ptv2)->tv_sec < (ptv1)->tv_sec || ((ptv2)->tv_sec == (ptv1)->tv_sec && (ptv2)->tv_usec < (ptv1)->tv_usec)) #define tv2LTtv1(ptv1, ptv2) ((ptv2)->tv_sec < (ptv1)->tv_sec || ((ptv2)->tv_sec == (ptv1)->tv_sec && (ptv2)->tv_usec < (ptv1)->tv_usec))
#define tv2LTEtv1(ptv1, ptv2) (tv2LTtv1(ptv2,ptv1) || ((ptv2)->tv_sec == (ptv1)->tv_sec && (ptv2)->tv_usec <= (ptv1)->tv_usec)) #define tv2LTEtv1(ptv1, ptv2) (tv2LTtv1(ptv2,ptv1) || ((ptv2)->tv_sec == (ptv1)->tv_sec && (ptv2)->tv_usec <= (ptv1)->tv_usec))
#define tvnonzero(ptv) ((ptv)->tv_sec != 0 || (ptv)->tv_usec != 0) #define tvnonzero(ptv) ((ptv)->tv_sec != 0 || (ptv)->tv_usec != 0)

View File

@@ -1868,6 +1868,34 @@ int ILibProcessPipe_Pipe_ReadEx(ILibProcessPipe_Pipe targetPipe, char *buffer, i
return(0); return(0);
} }
} }
BOOL ILibProcessPipe_Pipe_WriteEx_sink(void *chain, HANDLE h, ILibWaitHandle_ErrorStatus status, void* user)
{
ILibProcessPipe_PipeObject *j = (ILibProcessPipe_PipeObject*)user;
DWORD bytesWritten;
if (GetOverlappedResult(j->mPipe_WriteEnd, j->mwOverlapped, &bytesWritten, FALSE))
{
if (j->user4 != NULL)
{
((ILibProcessPipe_Pipe_WriteExHandler)j->user4)(j, j->user3, bytesWritten > 0 ? 0 : 1, (int)bytesWritten);
}
}
else
{
if (GetLastError() == ERROR_IO_PENDING)
{
return(TRUE);
}
else
{
if (j->user4 != NULL)
{
((ILibProcessPipe_Pipe_WriteExHandler)j->user4)(j, j->user3, 1, 0);
}
}
}
return(FALSE);
}
int ILibProcessPipe_Pipe_WriteEx(ILibProcessPipe_Pipe targetPipe, char *buffer, int bufferLength, void *user, ILibProcessPipe_Pipe_WriteExHandler OnWriteHandler) int ILibProcessPipe_Pipe_WriteEx(ILibProcessPipe_Pipe targetPipe, char *buffer, int bufferLength, void *user, ILibProcessPipe_Pipe_WriteExHandler OnWriteHandler)
{ {
ILibProcessPipe_PipeObject *j = (ILibProcessPipe_PipeObject*)targetPipe; ILibProcessPipe_PipeObject *j = (ILibProcessPipe_PipeObject*)targetPipe;
@@ -1875,18 +1903,48 @@ int ILibProcessPipe_Pipe_WriteEx(ILibProcessPipe_Pipe targetPipe, char *buffer,
{ {
void **extra; void **extra;
j->mwOverlapped = (OVERLAPPED*)ILibMemory_Allocate(sizeof(OVERLAPPED), sizeof(void*), NULL, (void**)&extra); j->mwOverlapped = (OVERLAPPED*)ILibMemory_Allocate(sizeof(OVERLAPPED), sizeof(void*), NULL, (void**)&extra);
if ((j->mwOverlapped->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL)) == NULL) { ILIBCRITICALEXIT(254); }
extra[0] = j; extra[0] = j;
} }
j->user3 = user; j->user3 = user;
j->user4 = OnWriteHandler; j->user4 = OnWriteHandler;
if (!WriteFileEx(j->mPipe_WriteEnd, buffer, bufferLength, j->mwOverlapped, ILibProcessPipe_Pipe_Write_CompletionRoutine))
if (!WriteFile(j->mPipe_WriteEnd, buffer, bufferLength, NULL, j->mwOverlapped))
{ {
return(GetLastError()); if (GetLastError() == ERROR_IO_PENDING)
{
ILibChain_AddWaitHandle(j->manager->ChainLink.ParentChain, j->mwOverlapped->hEvent, -1, ILibProcessPipe_Pipe_WriteEx_sink, j);
return(0);
}
// Error
if (OnWriteHandler != NULL) { OnWriteHandler(j, user, 1, 0); }
return(1);
} }
else else
{ {
// Write completed
if (OnWriteHandler != NULL) { OnWriteHandler(j, user, 0, bufferLength); }
return(0); return(0);
} }
// ILibProcessPipe_PipeObject *j = (ILibProcessPipe_PipeObject*)targetPipe;
// if (j->mwOverlapped == NULL)
// {
// void **extra;
// j->mwOverlapped = (OVERLAPPED*)ILibMemory_Allocate(sizeof(OVERLAPPED), sizeof(void*), NULL, (void**)&extra);
// extra[0] = j;
//}
// j->user3 = user;
// j->user4 = OnWriteHandler;
// if (!WriteFileEx(j->mPipe_WriteEnd, buffer, bufferLength, j->mwOverlapped, ILibProcessPipe_Pipe_Write_CompletionRoutine))
// {
// return(GetLastError());
// }
// else
// {
// return(0);
// }
} }
DWORD ILibProcessPipe_Process_GetPID(ILibProcessPipe_Process p) { return(p != NULL ? (DWORD)((ILibProcessPipe_Process_Object*)p)->PID : 0); } DWORD ILibProcessPipe_Process_GetPID(ILibProcessPipe_Process p) { return(p != NULL ? (DWORD)((ILibProcessPipe_Process_Object*)p)->PID : 0); }
#else #else