(main,print_usage) [_WIN32]: Add the ability to enable
empire thread debugging for Windows build. (empth_select) [_WIN32]: Fix empth_select() so can be aborted. The bug was that a command would not be aborted during an update. The problem was select() was not interrupt by the setting of the signalling wakeup event. Fix by replacing the select() with WSAEventSelect(). (empth_exit) [_WIN32]: Fix the shutdown sequence for Windows build to be running in empth_t context. Add a loc_RunThisThread() in empth_exit() before starting the shutdown() sequence.
This commit is contained in:
parent
1f9b34dfdd
commit
1bbd7e5342
3 changed files with 49 additions and 74 deletions
|
@ -60,7 +60,6 @@
|
|||
#include <windows.h>
|
||||
#include <process.h>
|
||||
|
||||
|
||||
#define loc_MIN_THREAD_STACK 16384
|
||||
|
||||
/************************
|
||||
|
@ -470,18 +469,19 @@ empth_exit(void)
|
|||
loc_debug("empth_exit");
|
||||
|
||||
if (pThread->bMainThread) {
|
||||
/* The main line. Wait forever. */
|
||||
while (1) {
|
||||
if (daemonize) {
|
||||
service_stopped();
|
||||
} else {
|
||||
if (daemonize)
|
||||
service_stopped(); /* Wait until the service is stopped */
|
||||
else {
|
||||
while (1) { /* server UI - Wait forever. */
|
||||
char buf[20];
|
||||
printf("\nEmpire Server>");
|
||||
fgets(buf, sizeof(buf), stdin);
|
||||
if (!strnicmp(buf, "quit", 4))
|
||||
shutdwn(0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
loc_RunThisThread();
|
||||
shutdwn(0);
|
||||
} else {
|
||||
TlsSetValue(loc_GVAR.dwTLSIndex, NULL);
|
||||
loc_FreeThreadInfo(pThread);
|
||||
|
@ -529,63 +529,32 @@ empth_terminate(empth_t *a)
|
|||
void
|
||||
empth_select(int fd, int flags)
|
||||
{
|
||||
WSAEVENT hEventObject[2];
|
||||
loc_Thread_t *pThread =
|
||||
(loc_Thread_t *)TlsGetValue(loc_GVAR.dwTLSIndex);
|
||||
fd_set readmask;
|
||||
fd_set writemask;
|
||||
struct lwpProc *proc;
|
||||
struct timeval tv;
|
||||
int n;
|
||||
|
||||
loc_debug("%s select on %d",
|
||||
flags == EMPTH_FD_READ ? "read" : "write", fd);
|
||||
loc_BlockThisThread();
|
||||
|
||||
while (1) {
|
||||
tv.tv_sec = 1000000;
|
||||
tv.tv_usec = 0;
|
||||
hEventObject[0] = WSACreateEvent();
|
||||
hEventObject[1] = pThread->hThreadEvent;
|
||||
|
||||
FD_ZERO(&readmask);
|
||||
FD_ZERO(&writemask);
|
||||
|
||||
switch (flags) {
|
||||
case EMPTH_FD_READ:
|
||||
FD_SET(fd, &readmask);
|
||||
break;
|
||||
case EMPTH_FD_WRITE:
|
||||
FD_SET(fd, &writemask);
|
||||
break;
|
||||
default:
|
||||
logerror("bad flag %d passed to empth_select", flags);
|
||||
empth_exit();
|
||||
}
|
||||
|
||||
n = select(fd + 1, &readmask, &writemask, (fd_set *) 0, &tv);
|
||||
|
||||
if (n < 0) {
|
||||
if (errno == EINTR) {
|
||||
/* go handle the signal */
|
||||
loc_debug("select broken by signal");
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
/* strange but we dont get EINTR on select broken by signal */
|
||||
loc_debug("select failed (%s)", strerror(errno));
|
||||
goto done;
|
||||
return;
|
||||
}
|
||||
|
||||
if (flags == EMPTH_FD_READ && FD_ISSET(fd, &readmask)) {
|
||||
loc_debug("input ready");
|
||||
break;
|
||||
}
|
||||
if (flags == EMPTH_FD_WRITE && FD_ISSET(fd, &writemask)) {
|
||||
loc_debug("output ready");
|
||||
break;
|
||||
}
|
||||
if (flags == EMPTH_FD_READ)
|
||||
WSAEventSelect(fd, hEventObject[0], FD_READ | FD_ACCEPT | FD_CLOSE);
|
||||
else if (flags == EMPTH_FD_WRITE)
|
||||
WSAEventSelect(fd, hEventObject[0], FD_WRITE | FD_CLOSE);
|
||||
else {
|
||||
logerror("bad flag %d passed to empth_select", flags);
|
||||
empth_exit();
|
||||
}
|
||||
|
||||
done:
|
||||
WSAWaitForMultipleEvents(2, hEventObject, FALSE, WSA_INFINITE, FALSE);
|
||||
|
||||
WSAEventSelect(fd, hEventObject[0], 0);
|
||||
|
||||
WSACloseEvent(hEventObject[0]);
|
||||
|
||||
loc_RunThisThread();
|
||||
}
|
||||
|
||||
|
|
|
@ -234,19 +234,21 @@ service_stopped(void)
|
|||
{
|
||||
if (hShutdownEvent != NULL) {
|
||||
WaitForSingleObject(hShutdownEvent,INFINITE);
|
||||
shutdwn(0);
|
||||
logerror("Service stopped");
|
||||
service_status.dwWin32ExitCode = 0;
|
||||
service_status.dwCurrentState = SERVICE_STOPPED;
|
||||
service_status.dwCheckPoint = 0;
|
||||
service_status.dwWaitHint = 0;
|
||||
|
||||
if (!SetServiceStatus (service_status_handle,
|
||||
&service_status)) {
|
||||
logerror("Error while stopping service SetServiceStatus"
|
||||
" error %ld", GetLastError());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
stop_service(void)
|
||||
{
|
||||
logerror("Service stopped");
|
||||
service_status.dwWin32ExitCode = 0;
|
||||
service_status.dwCurrentState = SERVICE_STOPPED;
|
||||
service_status.dwCheckPoint = 0;
|
||||
service_status.dwWaitHint = 0;
|
||||
|
||||
if (!SetServiceStatus (service_status_handle, &service_status))
|
||||
logerror("Error while stopping service SetServiceStatus"
|
||||
" error %ld", GetLastError());
|
||||
}
|
||||
|
||||
#endif /* _WIN32 */
|
||||
|
|
|
@ -87,14 +87,16 @@ static void
|
|||
print_usage(char *program_name)
|
||||
{
|
||||
#if defined(_WIN32)
|
||||
printf("Usage: %s -i -I service_name -r -R service_name -D datadir -e config_file -d\n", program_name);
|
||||
printf("Usage: %s -i -I service_name -r -R service_name -D datadir -e config_file -d -p\n",
|
||||
program_name);
|
||||
printf("-i install service with the default name %s\n", DEFAULT_SERVICE_NAME);
|
||||
printf("-r remove service with the default name %s\n", DEFAULT_SERVICE_NAME);
|
||||
|
||||
#else
|
||||
printf("Usage: %s -D datadir -e config_file -d -p -s\n", program_name);
|
||||
printf("-p print flag\n");
|
||||
printf("-s stack check flag (include print flag)\n");
|
||||
#endif
|
||||
printf("-p print flag\n");
|
||||
printf("-d debug mode\n");
|
||||
}
|
||||
|
||||
|
@ -112,7 +114,7 @@ main(int argc, char **argv)
|
|||
int op;
|
||||
|
||||
#if defined(_WIN32)
|
||||
while ((op = getopt(argc, argv, "D:de:iI:rR:h")) != EOF) {
|
||||
while ((op = getopt(argc, argv, "D:de:iI:rR:hp")) != EOF) {
|
||||
#else
|
||||
while ((op = getopt(argc, argv, "D:de:psh")) != EOF) {
|
||||
#endif
|
||||
|
@ -130,6 +132,10 @@ main(int argc, char **argv)
|
|||
case 'e':
|
||||
config_file = optarg;
|
||||
break;
|
||||
case 'p':
|
||||
flags |= EMPTH_PRINT;
|
||||
daemonize = 0;
|
||||
break;
|
||||
#if defined(_WIN32)
|
||||
case 'I':
|
||||
service_name = optarg;
|
||||
|
@ -149,10 +155,6 @@ main(int argc, char **argv)
|
|||
remove_service_set++;
|
||||
break;
|
||||
#else
|
||||
case 'p':
|
||||
flags |= EMPTH_PRINT;
|
||||
daemonize = 0;
|
||||
break;
|
||||
case 's':
|
||||
flags |= EMPTH_PRINT | EMPTH_STACKCHECK;
|
||||
daemonize = 0;
|
||||
|
@ -478,8 +480,10 @@ shutdwn(int sig)
|
|||
finish_server();
|
||||
|
||||
#if defined(_WIN32)
|
||||
if (daemonize)
|
||||
if (daemonize) {
|
||||
stop_service();
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
_exit(0);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue