void MainWindow::CmdComplicated() { sProgressDialog::Open(L"Complicated operation",L"Counting sheep..."); sProgressDialog::PushLevelCounter(0,2); static sInt count = 50; for(sInt i=0;i<count;i++) { if(!sProgressDialog::SetProgress(1.0f * i / count)) { sProgressDialog::Close(); return; } sSleep(50); } sProgressDialog::PopLevel(); sProgressDialog::SetText(L"Counting sheep in reverse..."); sProgressDialog::PushLevelCounter(1,2); for(sInt i=0;i<count;i++) { if(!sProgressDialog::SetProgress(1.0f * i / count)) { sProgressDialog::Close(); return; } sSleep(50); } sProgressDialog::Close(); }
void *ProcessThread::ThreadEntryRoutine(gxThread_t *thread) { servercfg->process_lock.MutexLock(); while(servercfg->process_loop) { if(servercfg->kill_server) break; if(servercfg->restart_server) break; // Block this thread from its own execution servercfg->process_cond.ConditionWait(&servercfg->process_lock); } sSleep(1); // Allow for I/O recovery time before exiting the program return (void *)0; }
void sMain() { sGetMemHandler(sAMF_HEAP)->MakeThreadSafe(); // WTF?! { sThread serve(ServerThread); sCatchCtrlC(); while(!sGotCtrlC()) sSleep(100); } sPrintF(L"Server quit.\n"); }
int StopProc() { if(servercfg->debug && servercfg->log_level == 0) servercfg->log_level = 1; servercfg->server_retry = 0; int retries = 3; while(StopThreads() != 0 && retries--) sleep(1); // Signal the process thread to exit servercfg->kill_server = 1; servercfg->process_loop = 0; servercfg->process_cond.ConditionSignal(); servercfg->process_lock.MutexUnlock(); NT_print("Sending termination signal to end process"); sSleep(1); return 1; }
sBool sMiniFTPClient::TryReconnect(sInt attempts,sInt startDelay) { if(State == CS_NOTARGET) return sFALSE; if(RetryLastTime && (sGetTime() - RetryLastTime) < ReconnectTimeout) return sFALSE; sInt delay = (startDelay != -1) ? startDelay : InitialTimeout; for(sInt i=0;i<attempts;i++) { Socket.Connect(TargetAddress,TargetPort); if(Socket.IsConnected()) break; // attempt failed, wait a bit and try again. wait duration doubles // every time. if(i != attempts-1) { sSleep(delay); delay *= 2; } } if(Socket.IsConnected()) { State = CS_CONNECTED; Error = sMFE_OK; RetryLastTime = 0; return sTRUE; } if(attempts > 1) sLogF(L"MiniFTP",L"Connection to %s:%d failed after %d attempts.\n",TargetHost,TargetPort,attempts); else sLogF(L"MiniFTP",L"Connection to %s:%d failed.\n",TargetHost,TargetPort); RetryLastTime = ReconnectTimeout ? sGetTime() : 0; Error = sMFE_NOCONNECT; return sFALSE; }
// wait for read/write to get available sBool sUDPSocket::Wait(sBool read, sBool write, sInt timeout) { if (!P || (!read && !write)) { sSleep(timeout); return sFALSE; } fd_set readset, writeset; FD_ZERO(&readset); FD_ZERO(&writeset); sInt nfds=0; if (read) { sFD_SET(P->Socket,&readset,nfds); } if (write) { sFD_SET(P->Socket,&writeset,nfds); } timeval tv; tv.tv_sec=timeout/1000; tv.tv_usec=(timeout%1000)*1000; sInt res=select(nfds,&readset,&writeset,0,timeout?&tv:0); return res!=-1 && (FD_ISSET(P->Socket,&readset)||FD_ISSET(P->Socket,&writeset)); }
int StopThreads() { servercfg->accept_clients = 0; servercfg->echo_loop = 0; unsigned num_threads = 0; gxString message; ProcessThread t; int error_level = 0; // If client or non-interactive command stop the console thread if(servercfg->console_thread) { LogProcMessage("Stopping CM console_thread"); if(servercfg->console_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { t.CancelThread(servercfg->console_thread); sSleep(1); // Allow I/O recovery time t.JoinThread(servercfg->console_thread); if(servercfg->console_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("CM console_thread was halted"); } else { LogProcMessage("CM console_thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("CM console_thread was stopped"); } if(error_level == 0) { delete servercfg->console_thread; servercfg->console_thread = 0; } } else { LogProcMessage("CM console_thread not active"); } // Stop the CM crons first if(servercfg->crontab_thread) { LogProcMessage("Stopping CM crontab_thread"); if(servercfg->crontab_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { t.CancelThread(servercfg->crontab_thread); sSleep(1); // Allow I/O recovery time t.JoinThread(servercfg->crontab_thread); if(servercfg->crontab_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("CM crontab_thread was halted"); } else { LogProcMessage("CM crontab_thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("CM crontab_thread was stopped"); } if(error_level == 0) { delete servercfg->crontab_thread; servercfg->crontab_thread = 0; } } else { LogProcMessage("CM crontab_thread not active"); } // Release all floating IP addresses if(servercfg->ipaddr_thread) { LogProcMessage("Stopping CM ipaddr_thread"); if(servercfg->ipaddr_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { t.CancelThread(servercfg->ipaddr_thread); sSleep(1); // Allow I/O recovery time t.JoinThread(servercfg->ipaddr_thread); if(servercfg->ipaddr_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("CM ipaddr_thread was halted"); } else { LogProcMessage("CM ipaddr_thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("CM ipaddr_thread was stopped"); } if(error_level == 0) { delete servercfg->ipaddr_thread; servercfg->ipaddr_thread = 0; } } else { LogProcMessage("CM ipaddr_thread not active"); } // The the other nodes to take over if(servercfg->keep_alive_thread) { LogProcMessage("Stopping CM UDP keep alive thread"); if(servercfg->keep_alive_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { t.CancelThread(servercfg->keep_alive_thread); sSleep(1); // Allow I/O recovery time t.JoinThread(servercfg->keep_alive_thread); if(servercfg->keep_alive_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("CM UDP keep alive thread was halted"); } else { LogProcMessage("CM UDP keep alive thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("CM UDP keep alive thread was stopped"); } if(error_level == 0) { delete servercfg->keep_alive_thread; servercfg->keep_alive_thread = 0; } } else { LogProcMessage("CM UDP keep alive thread not active"); } if(servercfg->udp_server_thread) { LogProcMessage("Stopping CM UDP server thread"); if(servercfg->udp_server_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { t.CancelThread(servercfg->udp_server_thread); sSleep(1); // Allow I/O recovery time t.JoinThread(servercfg->udp_server_thread); if(servercfg->udp_server_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("CM UDP server thread was halted"); } else { LogProcMessage("CM UDP server thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("CM UDP server thread was stopped"); } if(error_level == 0) { delete servercfg->udp_server_thread; servercfg->udp_server_thread = 0; } } else { LogProcMessage("CM UDP server thread not active"); } if(servercfg->client_request_pool ) { if(!servercfg->client_request_pool->IsEmpty()) { LogProcMessage("Closing all open TCP client threads"); thrPoolNode *ptr = servercfg->client_request_pool->GetHead(); while(ptr) { gxThread_t *thread = ptr->GetThreadPtr(); if(thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { num_threads++; t.CancelThread(thread); LogProcMessage("Shutting down TCP client thread"); t.JoinThread(thread); if(thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("Client TCP thread was canceled"); } else { LogProcMessage("Client TCP thread was not canceled"); error_level = 1; } } ptr = ptr->GetNext(); } message << clear << "Found " << num_threads << " working TCP client threads"; LogProcMessage(message.c_str()); if(error_level == 0) { t.DestroyThreadPool(servercfg->client_request_pool); servercfg->client_request_pool = 0; } } else { LogProcMessage("No open TCP connections"); } } if(servercfg->applications_thread) { LogProcMessage("Stopping CM applications_thread"); if(servercfg->applications_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { t.CancelThread(servercfg->applications_thread); sSleep(1); // Allow I/O recovery time t.JoinThread(servercfg->applications_thread); if(servercfg->applications_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("CM applications_thread was halted"); } else { LogProcMessage("CM applications_thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("CM applications_thread was stopped"); } if(error_level == 0) { delete servercfg->applications_thread; servercfg->applications_thread = 0; } } else { LogProcMessage("CM applications_thread not active"); } if(servercfg->services_thread) { LogProcMessage("Stopping CM services_thread"); if(servercfg->services_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { t.CancelThread(servercfg->services_thread); sSleep(1); // Allow I/O recovery time t.JoinThread(servercfg->services_thread); if(servercfg->services_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("CM services_thread was halted"); } else { LogProcMessage("CM services_thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("CM services_thread was stopped"); } if(error_level == 0) { delete servercfg->services_thread; servercfg->services_thread = 0; } } else { LogProcMessage("CM services_thread not active"); } if(servercfg->filesystems_thread) { LogProcMessage("Stopping CM filesystems_thread"); if(servercfg->filesystems_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { t.CancelThread(servercfg->filesystems_thread); sSleep(1); // Allow I/O recovery time t.JoinThread(servercfg->filesystems_thread); if(servercfg->filesystems_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("CM filesystems_thread was stopped"); } else { LogProcMessage("CM filesystems_thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("CM filesystems_thread was halted"); } if(error_level == 0) { delete servercfg->filesystems_thread; servercfg->filesystems_thread = 0; } } else { LogProcMessage("CM filesystems_thread not active"); } // Stop the log thread last if(servercfg->log_thread) { LogProcMessage("Stopping log thread"); LogThread log; if(servercfg->log_thread->GetThreadState() == gxTHREAD_STATE_RUNNING) { log.CancelThread(servercfg->log_thread); sSleep(1); log.JoinThread(servercfg->log_thread); if(servercfg->log_thread->GetThreadState() == gxTHREAD_STATE_CANCELED) { LogProcMessage("Log thread was halted"); } else { LogProcMessage("Log thread did not shutdown properly"); error_level = 1; } } else { LogProcMessage("Log thread was stopped"); } if(error_level == 0) { delete servercfg->log_thread; servercfg->log_thread = 0; } } else { LogProcMessage("Log thread not active"); } LogThread log_t; log_t.flush_all_logs(); return error_level; }
void termination_handler(int signum) // UNIX signal hander used to handle process termination signals { sigset_t mask_set; sigset_t old_set; int retries = 3; gxString sbuf; #ifndef __DEBUG__ if(signum == SIGSEGV) { signal(SIGSEGV, termination_handler); // Reset the signal handler again sigfillset(&mask_set); // Make any further signals while in handler sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process received segmentation violation"); StopProc(); ExitProc(1); sigprocmask(SIG_SETMASK, &old_set, NULL); // Restore the old signal mask2 return; } if(signum == SIGBUS) { signal(SIGBUS, termination_handler); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process received bus violation"); StopProc(); sigprocmask(SIG_SETMASK, &old_set, NULL); ExitProc(1); } #endif if(signum == SIGINT) { signal(SIGINT, SIG_IGN); // Log first and ignore all others sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process interrupted with Ctrl-C"); while(!StopProc() && --retries) sSleep(1); sigprocmask(SIG_SETMASK, &old_set, NULL); if(!retries) ExitProc(1); ExitProc(0); } if(signum == SIGQUIT) { signal(SIGQUIT, SIG_IGN); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process interrupted Ctrl-backslash"); sigprocmask(SIG_SETMASK, &old_set, NULL); return; } if(signum == SIGTERM) { signal(SIGTERM, termination_handler); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process terminated by kill command"); while(!StopProc() && --retries) sSleep(1); sigprocmask(SIG_SETMASK, &old_set, NULL); if(!retries) ExitProc(1); ExitProc(0); } if(signum == SIGHUP) { signal(SIGHUP, termination_handler); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process received hangup"); sigprocmask(SIG_SETMASK, &old_set, NULL); return; } if(signum == SIGKILL) { signal(SIGKILL, termination_handler); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process terminated by SIGKILL"); while(!StopProc() && --retries) sSleep(1); sigprocmask(SIG_SETMASK, &old_set, NULL); if(!retries) ExitProc(1); ExitProc(0); } if(signum == SIGTSTP) { signal(SIGTSTP, termination_handler); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process received suspend from Ctrl-Z"); sigprocmask(SIG_SETMASK, &old_set, NULL); return; } if(signum == SIGABRT) { signal(SIGABRT, termination_handler); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process received SIGABRT"); sigprocmask(SIG_SETMASK, &old_set, NULL); return; } if(signum == SIGUSR1) { signal(SIGUSR1, termination_handler); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process received SIGUSR1, lowering debug level"); if(!servercfg->debug) LogProcMessage("Debug mode is disabled"); if(servercfg->debug && servercfg->debug_level > 0) { servercfg->debug_level--; if(servercfg->debug_level <= 0) { LogProcMessage("Debug mode has been disabled"); servercfg->debug = 0; servercfg->debug_level = 0; } else { sbuf << clear << "Debug level decresed to " << servercfg->debug_level; LogProcMessage(sbuf.c_str()); } } sigprocmask(SIG_SETMASK, &old_set, NULL); return; } if(signum == SIGUSR2) { signal(SIGUSR2, termination_handler); sigfillset(&mask_set); sigprocmask(SIG_SETMASK, &mask_set, &old_set); LogProcMessage("Process received SIGUSR2, raising debug level"); if(servercfg->debug) { LogProcMessage("Debug mode is enabled"); } if(!servercfg->debug) { LogProcMessage("Debug mode has been enabled"); servercfg->debug = 1; servercfg->debug_level = 1; } if(servercfg->debug && servercfg->debug_level >= 1) { servercfg->debug_level++; if(servercfg->debug_level >= 5) { LogProcMessage("Debug mode set to level 5"); servercfg->debug = 1; servercfg->debug_level = 5; } else { sbuf << clear << "Debug level increased to " << servercfg->debug_level; LogProcMessage(sbuf.c_str()); } } sigprocmask(SIG_SETMASK, &old_set, NULL); return; } }
sBool sTCPHostSocket::WaitForEvents(sInt &numreads, sTCPSocket **reads, sInt& numwrites, sTCPSocket **writes, sTCPSocket **newconn, sInt timeout) { if (newconn) *newconn=0; if (!IsConnected()) { numreads=numwrites=0; return sFALSE; } fd_set readset, writeset; sInt nfds = 0; FD_ZERO(&readset); FD_ZERO(&writeset); for (sInt i=0; i<numreads; i++) sFD_SET(reads[i]->P->Socket,&readset,nfds); for (sInt i=0; i<numwrites; i++) sFD_SET(writes[i]->P->Socket,&writeset,nfds); sInt realnumreads=numreads; if (newconn) { sFD_SET(P->Socket,&readset,nfds); realnumreads++; } if (!realnumreads && !numwrites) { sSleep(timeout); return sTRUE; } timeval tv; tv.tv_sec=timeout/1000; tv.tv_usec=(timeout%1000)*1000; sInt res=select(nfds,(realnumreads?&readset:0),(numwrites?&writeset:0),0,(timeout>=0?&tv:0)); if (res==sSOCKET_ERROR) { P->HandleError(); numreads=numwrites=0; return sFALSE; } // new connection? if (FD_ISSET(P->Socket,&readset)) { *newconn=Accept(); if (!*newconn) { numreads=numwrites=0; return sFALSE; } } // read set... sInt nr=0; for (sInt i=0; i<numreads; i++) if (FD_ISSET(reads[i]->P->Socket,&readset)) reads[nr++]=reads[i]; numreads=nr; // write set... sInt nw=0; for (sInt i=0; i<numwrites; i++) if (FD_ISSET(writes[i]->P->Socket,&writeset)) writes[nw++]=writes[i]; numwrites=nw; return sTRUE; }