int start_server() { int child_indx, pid, i, ctl_socket; int childs, freeservers, used, maxrequests, ret; char command_buffer[COMMANDS_BUFFER_SIZE]; int user_informed = 0; ctl_socket = ci_named_pipe_create(CONF.COMMANDS_SOCKET); if (ctl_socket < 0) { ci_debug_printf(1, "Error opening control socket %s. Fatal error, exiting!\n", CONF.COMMANDS_SOCKET); exit(0); } if (!ci_proc_mutex_init(&accept_mutex)) { ci_debug_printf(1, "Can't init mutex for accepting conenctions. Fatal error, exiting!\n"); exit(0); } childs_queue = malloc(sizeof(struct childs_queue)); if (!create_childs_queue(childs_queue, 2 * CONF.MAX_SERVERS)) { ci_proc_mutex_destroy(&accept_mutex); ci_debug_printf(1, "Can't init shared memory. Fatal error, exiting!\n"); exit(0); } init_commands(); pid = 1; #ifdef MULTICHILD if (CONF.START_SERVERS > CONF.MAX_SERVERS) CONF.START_SERVERS = CONF.MAX_SERVERS; for (i = 0; i < CONF.START_SERVERS; i++) { if (pid) pid = start_child(LISTEN_SOCKET); } if (pid != 0) { main_signals(); while (1) { if ((ret = wait_for_commands(ctl_socket, command_buffer, 1)) > 0) { ci_debug_printf(5, "I received the command: %s\n", command_buffer); handle_monitor_process_commands(command_buffer); } if (ret < 0) { /*Eof received on pipe. Going to reopen ... */ ci_named_pipe_close(ctl_socket); ctl_socket = ci_named_pipe_open(CONF.COMMANDS_SOCKET); if (ctl_socket < 0) { ci_debug_printf(1, "Error opening control socket. We are unstable and going down!"); c_icap_going_to_term = 1; } } if (c_icap_going_to_term) break; childs_queue_stats(childs_queue, &childs, &freeservers, &used, &maxrequests); ci_debug_printf(10, "Server stats: \n\t Children: %d\n\t Free servers: %d\n" "\tUsed servers:%d\n\tRequests served:%d\n", childs, freeservers, used, maxrequests); if (MAX_REQUESTS_PER_CHILD > 0 && (child_indx = find_a_child_nrequests (childs_queue, MAX_REQUESTS_PER_CHILD)) >= 0) { ci_debug_printf(8, "Max requests reached for child :%d of pid :%d\n", child_indx, childs_queue->childs[child_indx].pid); pid = start_child(LISTEN_SOCKET); // usleep(500); childs_queue->childs[child_indx].father_said = GRACEFULLY; /*kill a server ... */ kill(childs_queue->childs[child_indx].pid, SIGTERM); } else if ((freeservers <= CONF.MIN_SPARE_THREADS && childs < CONF.MAX_SERVERS) || childs < CONF.START_SERVERS) { ci_debug_printf(8, "Free Servers: %d, children: %d. Going to start a child .....\n", freeservers, childs); pid = start_child(LISTEN_SOCKET); } else if (freeservers >= CONF.MAX_SPARE_THREADS && childs > CONF.START_SERVERS && (freeservers - CONF.THREADS_PER_CHILD) > CONF.MIN_SPARE_THREADS) { if ((child_indx = find_an_idle_child(childs_queue)) >= 0) { childs_queue->childs[child_indx].father_said = GRACEFULLY; ci_debug_printf(8, "Free Servers: %d, children: %d. Going to stop child %d(index: %d)\n", freeservers, childs, childs_queue->childs[child_indx].pid, child_indx); /*kill a server ... */ kill(childs_queue->childs[child_indx].pid, SIGTERM); user_informed = 0; } } else if (childs == CONF.MAX_SERVERS && freeservers < CONF.MIN_SPARE_THREADS) { if(! user_informed) { ci_debug_printf(1, "ATTENTION!!!! Not enough available servers (children %d, free servers %d, used servers %d)!!!!! " "Maybe you should increase the MaxServers and the " "ThreadsPerChild values in c-icap.conf file!!!!!!!!!",childs , freeservers, used); user_informed = 1; } } if (c_icap_going_to_term) break; check_for_exited_childs(); if (c_icap_reconfigure) { c_icap_reconfigure = 0; if (!server_reconfigure()) { ci_debug_printf(1, "Error while reconfiguring, exiting!\n"); break; } } } /*Main process exit point */ ci_debug_printf(1, "Possibly a term signal received. Monitor process going to term all children\n"); kill_all_childs(); system_shutdown(); ci_debug_printf(1, "Exiting....\n"); return 1; } #else child_data = (child_shared_data_t *) malloc(sizeof(child_shared_data_t)); child_data->pid = 0; child_data->freeservers = CONF.THREADS_PER_CHILD; child_data->usedservers = 0; child_data->requests = 0; child_data->connections = 0; child_data->to_be_killed = 0; child_data->father_said = 0; child_data->idle = 1; child_data->stats_size = ci_stat_memblock_size(); child_data->stats = malloc(child_data->stats_size); child_data->stats->sig = MEMBLOCK_SIG; ci_stat_attach_mem(child_data->stats, child_data->stats_size, NULL); child_main(LISTEN_SOCKET, 0); ci_proc_mutex_destroy(&accept_mutex); destroy_childs_queue(childs_queue); #endif return 1; }
void nmr_exit(char *modeptr) /********/ /* exit from nmr program */ { static int exiting = 0; /* prevent interrupts from re-scheduling this routine */ int enumber; (void) modeptr; if (!exiting) { exiting = 1; #ifdef SUN interact_kill(""); /* Kill all interactive acquisition progs */ #endif #ifdef VNMRJ frame_update("exit", "closeFrames"); stop_acqi( 1 ); autoqMsgOff(); #endif flush(99,NULL,0,NULL); if (mode_of_vnmr == FOREGROUND) WrestoreTerminal(); enumber = expdir_to_expnum(curexpdir); if (enumber > 0) unlockExperiment( enumber, mode_of_vnmr ); /* If the current experiment is not purged (delete older versions of a file) excess copies of curpar, procpar, etc. accumulate. */ closeVnmrInfo(); #ifdef X11 save_vnmr_geom(); #endif #ifdef VNMRJ unlink_alphafile(); if (access( Jvbgname, 0 ) == 0) unlink( Jvbgname ); if (!Bnmr) { char path[MAXPATH]; sprintf(path,"%s/persistence/.vp_%d_%d", userdir, jParent, jcurwin_cexpn()); unlink(path); } #endif kill_all_childs(); #ifndef VNMRJ exitTclInfo(); #endif clear_acq(); if(part11System) p11_saveAuditTrail(); if ( (mode_of_vnmr == BACKGROUND) && autoDelExp) { char *argv[1]; argv[0] = "autoDELEXP"; delexp(1,argv,0,NULL); } exit(0); } }