void servmgr (void) { int status; BINKD_CONFIG *config; srand(time(0)); setproctitle ("server manager"); Log (4, "servmgr started"); #if defined(HAVE_FORK) && !defined(HAVE_THREADS) blocksig(); signal (SIGCHLD, sighandler); #endif /* Loop on socket (listen can be changed by reload) * do_server() will return 0 to restart and -1 to terminate */ do { config = lock_current_config(); status = do_server(config); unlock_config_structure(config, 0); } while (status == 0 && !binkd_exit); Log(4, "downing servmgr..."); pidsmgr = 0; PostSem(&eothread); }
static void call (void *arg) { struct call_args *a = arg; char szDestAddr[FTN_ADDR_SZ + 1]; #if defined(WITH_PERL) && defined(HAVE_THREADS) void *cperl; #endif #if defined(WITH_PERL) && defined(HAVE_THREADS) cperl = perl_init_clone(a->config); #endif if (bsy_add (&a->node->fa, F_CSY, a->config)) { call0 (a->node, a->config); bsy_remove (&a->node->fa, F_CSY, a->config); } else { ftnaddress_to_str (szDestAddr, &a->node->fa); Log (4, "%s busy, skipping", szDestAddr); } #if defined(WITH_PERL) && defined(HAVE_THREADS) perl_done_clone(cperl); #endif unlock_config_structure(a->config, 0); free (arg); rel_grow_handles(-6); #ifdef HAVE_THREADS threadsafe(--n_clients); PostSem(&eothread); if (poll_flag) PostSem(&wakecmgr); _endthread(); #elif defined(DOS) || defined(DEBUGCHILD) --n_clients; #endif }
static void serv (void *arg) { int h = *(int *) arg; BINKD_CONFIG *config; #if defined(WITH_PERL) && defined(HAVE_THREADS) void *cperl; #endif #if defined(HAVE_FORK) && !defined(HAVE_THREADS) && !defined(DEBUGCHILD) int curfd; pidcmgr = 0; for (curfd=0; curfd<sockfd_used; curfd++) soclose(sockfd[curfd]); #endif config = lock_current_config(); #if defined(WITH_PERL) && defined(HAVE_THREADS) cperl = perl_init_clone(config); #endif protocol (h, h, NULL, NULL, NULL, NULL, NULL, config); Log (5, "downing server..."); #if defined(WITH_PERL) && defined(HAVE_THREADS) perl_done_clone(cperl); #endif del_socket(h); soclose (h); free (arg); unlock_config_structure(config, 0); rel_grow_handles (-6); #ifdef HAVE_THREADS threadsafe(--n_servers); PostSem(&eothread); ENDTHREAD(); #elif defined(DOS) || defined(DEBUGCHILD) --n_servers; #endif }
void clientmgr (void *arg) { int status; BINKD_CONFIG *config = NULL; #if defined(WITH_PERL) && defined(HAVE_THREADS) void *cperl = NULL; #endif UNUSED_ARG(arg); #ifdef HAVE_FORK pidcmgr = 0; pidCmgr = (int) getpid(); blocksig(); signal (SIGCHLD, sighandler); #elif HAVE_THREADS pidcmgr = PID(); #endif config = lock_current_config(); #if defined(WITH_PERL) && defined(HAVE_THREADS) if (server_flag) cperl = perl_init_clone(config); #endif setproctitle ("client manager"); Log (4, "clientmgr started"); for (;;) { if (config != current_config) { #if defined(WITH_PERL) && defined(HAVE_THREADS) if (server_flag && cperl) perl_done_clone(cperl); #endif if (config) unlock_config_structure(config, 0); config = lock_current_config(); #if defined(WITH_PERL) && defined(HAVE_THREADS) if (server_flag) cperl = perl_init_clone(config); #endif } status = do_client(config); if (status != 0 || binkd_exit) break; if ( #ifdef HAVE_THREADS !server_flag && #endif !poll_flag) checkcfg(); } Log (5, "downing clientmgr..."); #if defined(WITH_PERL) && defined(HAVE_THREADS) if (server_flag && cperl) perl_done_clone(cperl); #endif unlock_config_structure(config, 0); unblocksig(); #ifdef HAVE_THREADS pidcmgr = 0; PostSem(&eothread); if (binkd_exit) _endthread(); #endif exit (0); }
/* * Run one client loop. Return -1 to exit */ static int do_client(BINKD_CONFIG *config) { FTN_NODE *r; int pid; if (!config->q_present) { q_free (SCAN_LISTED, config); if (config->printq) Log (-1, "scan\r"); q_scan (SCAN_LISTED, config); config->q_present = 1; if (config->printq) { LockSem (&lsem); q_list (stderr, SCAN_LISTED, config); ReleaseSem (&lsem); Log (-1, "idle\r"); } } if (n_clients < config->max_clients) { if ((r = q_next_node (config)) != 0) { struct call_args args; if (!bsy_test (&r->fa, F_BSY, config) || !bsy_test (&r->fa, F_CSY, config)) { char szDestAddr[FTN_ADDR_SZ + 1]; ftnaddress_to_str (szDestAddr, &r->fa); Log (4, "%s busy, skipping", szDestAddr); return 0; /* go to the next node */ } rel_grow_handles (6); threadsafe(++n_clients); lock_config_structure(config); args.node = r; args.config = config; if ((pid = branch (call, &args, sizeof (args))) < 0) { unlock_config_structure(config, 0); rel_grow_handles (-6); threadsafe(--n_clients); PostSem(&eothread); Log (1, "cannot branch out"); unblocksig(); SLEEP(1); blocksig(); check_child(&n_clients); } #if !defined(DEBUGCHILD) else { Log (5, "started client #%i, id=%i", n_clients, pid); #if defined(HAVE_FORK) && !defined(AMIGA) unlock_config_structure(config, 0); /* Forked child has own copy */ #endif } #endif } else { if (poll_flag) { if (n_clients <= 0 && q_not_empty (config) == 0) { Log (4, "the queue is empty, quitting..."); return -1; } } else config->q_present = 0; unblocksig(); SLEEP (config->rescan_delay); blocksig(); check_child(&n_clients); } } else { unblocksig(); SLEEP (config->call_delay); blocksig(); check_child(&n_clients); } return 0; }