* if we had problems shutting down because of client threads still blocked, close all sessions fd's so they come to an end.
CtdlLogPrintf(CTDL_INFO, "Didn't terminate %d protected idle sessions;\n", killed);
}
+void terminate_stuck_sessions(void)
+{
+ CitContext *ccptr;
+ int killed = 0;
+
+ begin_critical_section(S_SESSION_TABLE);
+ for (ccptr = ContextList; ccptr != NULL; ccptr = ccptr->next) {
+ if (ccptr->client_socket != -1)
+ {
+ close(ccptr->client_socket);
+ ccptr->client_socket = -1;
+ killed++;
+ }
+ }
+ end_critical_section(S_SESSION_TABLE);
+ if (killed > 0)
+ CtdlLogPrintf(CTDL_INFO, "Flushed %d stuck sessions\n", killed);
+}
+
/*
void dead_session_purge(int force);
void set_async_waiting(struct CitContext *ccptr);
+/* forcibly close and flush fd's on shutdown */
+void terminate_stuck_sessions(void);
+
/* Deprecated, user CtdlBumpNewMailCounter() instead */
void BumpNewMailCounter(long) __attribute__ ((deprecated));
void CtdlRegisterSessionHook(void (*fcn_ptr)(void), int EventType);
void CtdlUnregisterSessionHook(void (*fcn_ptr)(void), int EventType);
+void CtdlShutdownServiceHooks(void);
void CtdlRegisterUserHook(void (*fcn_ptr)(struct ctdluser *), int EventType);
void CtdlUnregisterUserHook(void (*fcn_ptr)(struct ctdluser *), int EventType);
{
struct ServiceFunctionHook *cur, *p;
- for (cur = ServiceHookTable; cur != NULL; cur = cur->next) {
+ cur = ServiceHookTable;
+ while (cur != NULL) {
/* This will also remove duplicates if any */
while (cur != NULL &&
!(sockpath && cur->sockpath &&
}
}
+
+void CtdlShutdownServiceHooks(void)
+{
+ /* sort of a duplicate of close_masters() but called earlier */
+ struct ServiceFunctionHook *cur;
+
+ cur = ServiceHookTable;
+ while (cur != NULL)
+ {
+ if (cur->msock != -1)
+ {
+ close(cur->msock);
+ cur->msock = -1;
+ if (cur->sockpath != NULL){
+ CtdlLogPrintf(CTDL_INFO, "[%s] Closed UNIX domain socket %s\n",
+ cur->ServiceName,
+ cur->sockpath);
+ } else {
+ CtdlLogPrintf(CTDL_INFO, "[%s] closing service\n",
+ cur->ServiceName);
+ }
+ }
+ cur = cur->next;
+ }
+}
+
void CtdlDestroyServiceHook(void)
{
struct ServiceFunctionHook *cur, *p;
{
/* First run any registered shutdown hooks. This probably doesn't belong here. */
PerformSessionHooks(EVT_SHUTDOWN);
-
+
+ /* then close all tcp ports so nobody else can talk to us anymore. */
+ CtdlShutdownServiceHooks();
//FIXME: The signalling of the condition should not be in the critical_section
// We need to build a list of threads we are going to signal and then signal them afterwards
if ((that_thread->state == CTDL_THREAD_STOP_REQ || that_thread->state == CTDL_THREAD_STOPPING)
&& (!citthread_equal(that_thread->tid, citthread_self())))
- CtdlLogPrintf(CTDL_DEBUG, "Waiting for thread %s (0x%08lx) to exit.\n", that_thread->name, that_thread->tid);
+ {
+ CtdlLogPrintf(CTDL_DEBUG, "Waiting for thread %s (0x%08lx) to exit.\n", that_thread->name, that_thread->tid);
+ terminate_stuck_sessions();
+ }
else
{
/**