mirror of
https://github.com/Ylianst/MeshAgent
synced 2025-12-18 01:03:14 +00:00
Changed how the ForceUnblockPipe works on Linux, to not use fdopen/fdclose.
Also modified, so when flushing the ForceUnblockPipe, if the descriptor is invalid, it will recreate it, fixing a 100% CPU issue on linux, that seems to happen after a self-update.
This commit is contained in:
@@ -1082,8 +1082,7 @@ typedef struct ILibBaseChain
|
|||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
SOCKET TerminateSock;
|
SOCKET TerminateSock;
|
||||||
#else
|
#else
|
||||||
FILE *TerminateReadPipe;
|
int TerminatePipe[2];
|
||||||
FILE *TerminateWritePipe;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void *Timer;
|
void *Timer;
|
||||||
@@ -1876,10 +1875,9 @@ void ILibForceUnBlockChain(void* Chain)
|
|||||||
//
|
//
|
||||||
// Writing data on the pipe will trigger the select on Posix
|
// Writing data on the pipe will trigger the select on Posix
|
||||||
//
|
//
|
||||||
if (c->TerminateWritePipe != NULL)
|
if (c->TerminatePipe[1] != 0)
|
||||||
{
|
{
|
||||||
fprintf(c->TerminateWritePipe," ");
|
ignore_result(write(c->TerminatePipe[1], " ", 1));
|
||||||
fflush(c->TerminateWritePipe);
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
@@ -2028,7 +2026,7 @@ ILibExportMethod void ILibChain_Continue(void *Chain, ILibChain_Link **modules,
|
|||||||
//
|
//
|
||||||
// Put the Read end of the Pipe in the FDSET, for ILibForceUnBlockChain
|
// Put the Read end of the Pipe in the FDSET, for ILibForceUnBlockChain
|
||||||
//
|
//
|
||||||
FD_SET(fileno(root->TerminateReadPipe), &readset);
|
FD_SET(root->TerminatePipe[0], &readset);
|
||||||
#endif
|
#endif
|
||||||
sem_wait(&ILibChainLock);
|
sem_wait(&ILibChainLock);
|
||||||
while (ILibLinkedList_GetCount(((ILibBaseChain*)Chain)->LinksPendingDelete) > 0)
|
while (ILibLinkedList_GetCount(((ILibBaseChain*)Chain)->LinksPendingDelete) > 0)
|
||||||
@@ -2075,13 +2073,23 @@ ILibExportMethod void ILibChain_Continue(void *Chain, ILibChain_Link **modules,
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if (FD_ISSET(fileno(root->TerminateReadPipe), &readset))
|
if (FD_ISSET(root->TerminatePipe[0], &readset))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Empty the pipe
|
// Empty the pipe
|
||||||
//
|
//
|
||||||
while (fgetc(((struct ILibBaseChain*)Chain)->TerminateReadPipe) != EOF)
|
while ((vX = read(root->TerminatePipe[0], ILibScratchPad, sizeof(ILibScratchPad))) > 0);
|
||||||
|
if (vX == 0 || (errno != EAGAIN && errno != EWOULDBLOCK))
|
||||||
{
|
{
|
||||||
|
// Something happened
|
||||||
|
close(root->TerminatePipe[0]);
|
||||||
|
close(root->TerminatePipe[1]);
|
||||||
|
root->TerminatePipe[0] = root->TerminatePipe[1] = 0;
|
||||||
|
if (pipe(root->TerminatePipe) == 0)
|
||||||
|
{
|
||||||
|
fcntl(root->TerminatePipe[0], F_SETFL, O_NONBLOCK);
|
||||||
|
fcntl(root->TerminatePipe[1], F_SETFL, O_NONBLOCK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -2676,7 +2684,7 @@ char *ILibChain_GetMetaDataFromDescriptorSet(void *chain, fd_set *inr, fd_set *i
|
|||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
if (FD_ISSET(((ILibBaseChain*)chain)->TerminateSock, ine) || FD_ISSET(((ILibBaseChain*)chain)->TerminateSock, inr)) { ret = "ILibForceUnblockChain"; }
|
if (FD_ISSET(((ILibBaseChain*)chain)->TerminateSock, ine) || FD_ISSET(((ILibBaseChain*)chain)->TerminateSock, inr)) { ret = "ILibForceUnblockChain"; }
|
||||||
#else
|
#else
|
||||||
if (FD_ISSET(fileno(((ILibBaseChain*)chain)->TerminateReadPipe), inr)) { ret = "ILibForceUnblockChain"; }
|
if (FD_ISSET(((ILibBaseChain*)chain)->TerminatePipe[0], inr)) { ret = "ILibForceUnblockChain"; }
|
||||||
#endif
|
#endif
|
||||||
if (ret == NULL)
|
if (ret == NULL)
|
||||||
{
|
{
|
||||||
@@ -2738,10 +2746,6 @@ ILibExportMethod void ILibStartChain(void *Chain)
|
|||||||
struct timeval tv;
|
struct timeval tv;
|
||||||
int slct;
|
int slct;
|
||||||
int vX;
|
int vX;
|
||||||
#if !defined(WIN32) && !defined(_WIN32_WCE)
|
|
||||||
int TerminatePipe[2];
|
|
||||||
int flags;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (Chain == NULL) { return; }
|
if (Chain == NULL) { return; }
|
||||||
chain->PreSelectCount = chain->PostSelectCount = 0;
|
chain->PreSelectCount = chain->PostSelectCount = 0;
|
||||||
@@ -2781,18 +2785,16 @@ ILibExportMethod void ILibStartChain(void *Chain)
|
|||||||
FD_ZERO(&errorset);
|
FD_ZERO(&errorset);
|
||||||
FD_ZERO(&writeset);
|
FD_ZERO(&writeset);
|
||||||
|
|
||||||
#if !defined(WIN32) && !defined(_WIN32_WCE)
|
#if defined(_POSIX)
|
||||||
//
|
//
|
||||||
// For posix, we need to use a pipe to force unblock the select loop
|
// For posix, we need to use a pipe to force unblock the select loop
|
||||||
//
|
//
|
||||||
if (pipe(TerminatePipe) == -1) {} // TODO: Pipe error
|
if (pipe(chain->TerminatePipe) == 0)
|
||||||
flags = fcntl(TerminatePipe[0],F_GETFL,0);
|
{
|
||||||
//
|
// We need to set the pipe to nonblock, so we can blindly empty the pipe
|
||||||
// We need to set the pipe to nonblock, so we can blindly empty the pipe
|
fcntl(chain->TerminatePipe[0], F_SETFL, O_NONBLOCK);
|
||||||
//
|
fcntl(chain->TerminatePipe[1], F_SETFL, O_NONBLOCK);
|
||||||
fcntl(TerminatePipe[0],F_SETFL,O_NONBLOCK|flags);
|
}
|
||||||
((struct ILibBaseChain*)Chain)->TerminateReadPipe = fdopen(TerminatePipe[0],"r");
|
|
||||||
((struct ILibBaseChain*)Chain)->TerminateWritePipe = fdopen(TerminatePipe[1],"w");
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
chain->RunningFlag = 1;
|
chain->RunningFlag = 1;
|
||||||
@@ -2845,7 +2847,7 @@ ILibExportMethod void ILibStartChain(void *Chain)
|
|||||||
//
|
//
|
||||||
// Put the Read end of the Pipe in the FDSET, for ILibForceUnBlockChain
|
// Put the Read end of the Pipe in the FDSET, for ILibForceUnBlockChain
|
||||||
//
|
//
|
||||||
FD_SET(TerminatePipe[0], &readset);
|
FD_SET(chain->TerminatePipe[0], &readset);
|
||||||
#endif
|
#endif
|
||||||
sem_wait(&ILibChainLock);
|
sem_wait(&ILibChainLock);
|
||||||
while(ILibLinkedList_GetCount(((ILibBaseChain*)Chain)->LinksPendingDelete) > 0)
|
while(ILibLinkedList_GetCount(((ILibBaseChain*)Chain)->LinksPendingDelete) > 0)
|
||||||
@@ -2892,13 +2894,23 @@ ILibExportMethod void ILibStartChain(void *Chain)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef WIN32
|
#ifndef WIN32
|
||||||
if (FD_ISSET(TerminatePipe[0], &readset))
|
if (FD_ISSET(chain->TerminatePipe[0], &readset))
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
// Empty the pipe
|
// Empty the pipe
|
||||||
//
|
//
|
||||||
while (fgetc(((struct ILibBaseChain*)Chain)->TerminateReadPipe)!=EOF)
|
while ((vX = read(chain->TerminatePipe[0], ILibScratchPad, sizeof(ILibScratchPad))) > 0);
|
||||||
|
if (vX == 0 || (errno != EAGAIN && errno != EWOULDBLOCK))
|
||||||
{
|
{
|
||||||
|
// Something happened
|
||||||
|
close(chain->TerminatePipe[0]);
|
||||||
|
close(chain->TerminatePipe[1]);
|
||||||
|
chain->TerminatePipe[0] = chain->TerminatePipe[1] = 0;
|
||||||
|
if (pipe(chain->TerminatePipe) == 0)
|
||||||
|
{
|
||||||
|
fcntl(chain->TerminatePipe[0], F_SETFL, O_NONBLOCK);
|
||||||
|
fcntl(chain->TerminatePipe[1], F_SETFL, O_NONBLOCK);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@@ -3028,10 +3040,11 @@ ILibExportMethod void ILibStartChain(void *Chain)
|
|||||||
//
|
//
|
||||||
// Free the pipe resources
|
// Free the pipe resources
|
||||||
//
|
//
|
||||||
fclose(((ILibBaseChain*)Chain)->TerminateReadPipe);
|
close(((ILibBaseChain*)Chain)->TerminatePipe[0]);
|
||||||
fclose(((ILibBaseChain*)Chain)->TerminateWritePipe);
|
close(((ILibBaseChain*)Chain)->TerminatePipe[1]);
|
||||||
((ILibBaseChain*)Chain)->TerminateReadPipe=0;
|
|
||||||
((ILibBaseChain*)Chain)->TerminateWritePipe=0;
|
((ILibBaseChain*)Chain)->TerminatePipe[0] = 0;
|
||||||
|
((ILibBaseChain*)Chain)->TerminatePipe[1] = 0;
|
||||||
#endif
|
#endif
|
||||||
#if defined(WIN32)
|
#if defined(WIN32)
|
||||||
if (((ILibBaseChain*)Chain)->TerminateSock != ~0)
|
if (((ILibBaseChain*)Chain)->TerminateSock != ~0)
|
||||||
|
|||||||
Reference in New Issue
Block a user