Remove sleeps on proxy termination

This commit is contained in:
Vladimir Dubrovin 2026-10-10 23:28:19 +03:00
parent 77f8870c5d
commit c6e290b8e6
3 changed files with 63 additions and 11 deletions

View File

@ -74,13 +74,8 @@ void __stdcall CommandHandler( DWORD dwCommand )
SetStatus( SERVICE_STOP_PENDING, 0, 1 );
conf.timetoexit = 1;
conf.paused++;
Sleep(2000);
SetStatus( SERVICE_STOPPED, 0, 0 );
#ifdef WITH_ODBC
_3proxy_mutex_lock(&log_mutex);
close_sql();
_3proxy_mutex_unlock(&log_mutex);
#endif
/* ServiceMain() reports the service stopped once cyclestep() has
seen this and the services are done */
break;
case SERVICE_CONTROL_PAUSE:
SetStatus( SERVICE_PAUSE_PENDING, 0, 1 );
@ -106,6 +101,13 @@ void __stdcall ServiceMain(int argc, unsigned char* argv[] )
SetStatus( SERVICE_START_PENDING, 0, 1 );
SetStatus( SERVICE_RUNNING, 0, 0 );
cyclestep();
#ifdef WITH_ODBC
_3proxy_mutex_lock(&log_mutex);
close_sql();
_3proxy_mutex_unlock(&log_mutex);
#endif
/* the last thing: the process may be ended once this is reported */
SetStatus( SERVICE_STOPPED, 0, 0 );
}
#endif
@ -240,6 +242,39 @@ void dumpcounters(struct trafcount *tlin, int counterd){
}
}
/* Lets the services finish before the process exits, for EXITWAIT ms at
most: each one waits for its connections, and a connection may hang on
its peer. Posts left over from reloads are consumed on the way, the
count decides. */
#define EXITWAIT 3000
static unsigned long nowms(void){
#ifdef _WIN32
return (unsigned long)GetTickCount();
#else
struct timeval tv;
gettimeofday(&tv, NULL);
return (unsigned long)tv.tv_sec * 1000 + tv.tv_usec / 1000;
#endif
}
static void waitservices(void){
unsigned long start = nowms(), passed;
for(;;){
int n;
_3proxy_mutex_lock(&runningservices_mutex);
n = runningservices;
_3proxy_mutex_unlock(&runningservices_mutex);
if(!n) return;
/* a clock set back makes this huge, which ends the wait as well */
passed = nowms() - start;
if(passed >= EXITWAIT) return;
if(_3proxy_sem_timedlock(serviceexited, (unsigned)(EXITWAIT - passed))) return;
}
}
void cyclestep(void){
struct tm *tm;
time_t minutecounter;
@ -336,9 +371,7 @@ void cyclestep(void){
if(conf.timetoexit){
conf.paused++;
doschedule();
usleep(SLEEPTIME*999);
usleep(SLEEPTIME*999);
usleep(SLEEPTIME*999);
waitservices();
return;
}
@ -517,6 +550,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
}
_3proxy_mutex_init(&config_mutex);
_3proxy_mutex_init(&runningservices_mutex);
_3proxy_mutex_init(&bandlim_mutex);
_3proxy_mutex_init(&connlim_mutex);
_3proxy_mutex_init(&tc_mutex);
@ -524,7 +558,7 @@ int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int
#ifndef NORADIUS
_3proxy_mutex_init(&rad_mutex);
#endif
if(_3proxy_sem_init(conf.threadinit, 1, 1)){
if(_3proxy_sem_init(conf.threadinit, 1, 1) || _3proxy_sem_init_timed(serviceexited, 0, 0x7fffffff)){
fprintf(stderr, "semaphore init failed\n");
return 1;
}

View File

@ -38,6 +38,9 @@ _3proxy_mutex_t bandlim_mutex;
_3proxy_mutex_t connlim_mutex;
_3proxy_mutex_t tc_mutex;
_3proxy_mutex_t config_mutex;
int runningservices = 0;
_3proxy_mutex_t runningservices_mutex;
_3proxy_sem_t serviceexited;
int haveerror = 0;
int linenum = 0;
@ -76,7 +79,18 @@ DWORD WINAPI startsrv(LPVOID data) {
void * startsrv(void * data) {
#endif
struct child *d = (struct child *)data;
/* counted here rather than where the service is listed, so every way
out of it is counted too; start_proxy_thread() waits for the service
to start, so it is counted by the time that returns */
_3proxy_mutex_lock(&runningservices_mutex);
runningservices++;
_3proxy_mutex_unlock(&runningservices_mutex);
mainfunc(d->argc, (char **)d->argv);
_3proxy_mutex_lock(&runningservices_mutex);
runningservices--;
_3proxy_mutex_unlock(&runningservices_mutex);
_3proxy_sem_unlock(serviceexited);
return 0;
}

View File

@ -467,6 +467,10 @@ struct dictionary;
struct node;
struct property;
extern _3proxy_mutex_t config_mutex;
/* services running, and a post each time one of them has finished */
extern int runningservices;
extern _3proxy_mutex_t runningservices_mutex;
extern _3proxy_sem_t serviceexited;
extern _3proxy_mutex_t bandlim_mutex;
extern _3proxy_mutex_t connlim_mutex;
extern _3proxy_mutex_t tc_mutex;