/* Monolith chat ping thread. * - by Richard W.M. Jones * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Library General Public * License as published by the Free Software Foundation; either * version 2 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library General Public License for more details. * * You should have received a copy of the GNU Library General Public * License along with this library; if not, write to the Free * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * $Id: thread.c,v 1.4 2003/02/22 12:56:27 rich Exp $ */ #include "config.h" #include #include #include #include #include #include "chatroom.h" /* This is the chat ping thread. This thread sends out a blank message * to all rooms at a periodic interval. The reason for having this thread * at all is to stop proxy servers and browsers from timing out the * connection to the chat server. The blank message just ensures that some * more data is sent over the TCP connection. * * This thread also serves another useful purpose: if we lose the connection * to the user because of a network failure, then the blank message will * detect this too. * * This thread starts up as soon as the chat library (ie. libmonolithchat.so) * is loaded. We take care to kill the thread if the chat library is * unloaded. Because there is no way to explicitly kill a thread, we * have to set a 'quit' flag, and rely on the thread reading this flag * and exiting itself. There is an added complication here however. The * 'quit' flag itself cannot be allocated in static memory, because this * memory would be unmapped by the time the chat thread gets round to * reading it. So instead we allocate a byte in global_pool for this flag. */ static void chat_ping_thread_init (void) __attribute__((constructor)); static void chat_ping_thread_stop (void) __attribute__((destructor)); static void run (void *); static pool thread_pool = 0; static pseudothread pth; static unsigned char *quit_ptr; /* Address of the quit flag (see above). */ #define INTERVAL 120 /* Seconds between messages. */ static void chat_ping_thread_init () { if (thread_pool) abort (); /* Something very wrong has happened. */ /* Allocate memory for the quit flag from global_pool - not statically * because the memory would become unmapped before the thread would have * a chance to read it. */ quit_ptr = pmalloc (global_pool, sizeof (unsigned char)); *quit_ptr = 0; /* Create and start up the thread. */ thread_pool = new_pool (); pth = new_pseudothread (thread_pool, run, quit_ptr, "chat ping thread"); pth_start (pth); } static void chat_ping_thread_stop () { *quit_ptr = 1; } static void run (void *vp) { unsigned char *quit_ptr = (unsigned char *) vp; for (;;) { pth_sleep (INTERVAL); if (*quit_ptr) return; chatroom_spam_blank (thread_pool); } }