Is it possible for me to spin off my own thread to do background work separate from individual requests in a module? I am trying to start a thread from the instantiate call and then rejoin on the detach, this seems to work when I run radius -X, but something is happening when radius is not in debug so that it gets stuck or killed somehow, the log statement is only logged once. All I have is a while loop with a log and sleep statement in it as shown below. It is not getting stuck in the log call as even without that, sending a sigterm to the process still hangs. #include <freeradius/ident.h> RCSID("$Id$") #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <pthread.h> #include <freeradius-devel/radiusd.h> #include <freeradius-devel/modules.h> typedef struct rlm_gwis_t { int shutdown; pthread_t p_thread; } gw_config; const CONF_PARSER module_config[] = { { NULL, -1, 0, NULL, NULL } /* end the list */ }; void *gwis__background__start(void *data) { gw_config *gwd = data; if(!gwd) return NULL; while(!gwd->shutdown) { radlog(L_ERR, "Background process, shutdown %d", gwd->shutdown); sleep(1); } return NULL; } static int gwis_detach(void *gwd) { if(gwd) { ((gw_config *)gwd)->shutdown = 1; pthread_join(((gw_config *)gwd)->p_thread, NULL); free(gwd); } return RLM_MODULE_OK; } static int gwis_instantiate(CONF_SECTION *conf, void **gwd) { gw_config *tmp_gwd; tmp_gwd = rad_malloc(sizeof(gw_config)); if(!tmp_gwd) { return RLM_MODULE_FAIL; } memset(tmp_gwd, 0, sizeof(gw_config)); if(cf_section_parse(conf, tmp_gwd, module_config) < 0) { free(tmp_gwd); return RLM_MODULE_FAIL; } tmp_gwd->shutdown = 0; if(pthread_create(&tmp_gwd->p_thread, NULL, gwis__background__start, tmp_gwd)) { gwis_detach(tmp_gwd); return -1; } *gwd = tmp_gwd; return RLM_MODULE_OK; } static int gwis_preacct(void *gwd, REQUEST *request) { return RLM_MODULE_OK; } module_t rlm_gwis = { RLM_MODULE_INIT, "gwis", RLM_TYPE_THREAD_SAFE, gwis_instantiate, gwis_detach, { NULL, NULL, gwis_preacct, NULL, NULL, NULL, NULL, NULL }, };
James Devine wrote:
Is it possible for me to spin off my own thread to do background work separate from individual requests in a module?
No. Why would you do that? The OS already supports multiple processes. Just run another process. The RADIUS server is about doing RADIUS. It reads packets, processes them, and responds to packets. There are *no* threads except ones processing packets. There are *no* timer events, except those related to processing packets. Alan DeKok.
It is just easier and less expensive to operate a second thread since it will be tightly integrated with the threads spawned to handle requests. I can run a second process and use IPC if it is not possible to spawn another thread separate from requests. On Fri, May 22, 2009 at 2:15 PM, Alan DeKok <aland@deployingradius.com>wrote:
James Devine wrote:
Is it possible for me to spin off my own thread to do background work separate from individual requests in a module?
No.
Why would you do that? The OS already supports multiple processes. Just run another process.
The RADIUS server is about doing RADIUS. It reads packets, processes them, and responds to packets. There are *no* threads except ones processing packets. There are *no* timer events, except those related to processing packets.
Alan DeKok. - List info/subscribe/unsubscribe? See http://www.freeradius.org/list/users.html
participants (2)
-
Alan DeKok -
James Devine