void child_main(ci_socket sockfd) { int claddrlen = sizeof(ci_sockaddr_t); ci_thread_t thread; int i, retcode, haschild = 1, jobs_in_queue = 0; int pid = 0; char op; HANDLE hStdin; DWORD dwRead; // child_signals(); // pid=getpid(); hStdin = GetStdHandle(STD_INPUT_HANDLE); if ((hStdin == INVALID_HANDLE_VALUE)) ExitProcess(1); ci_thread_mutex_init(&threads_list_mtx); ci_thread_mutex_init(&counters_mtx); ci_thread_cond_init(&free_server_cond); threads_list = (server_decl_t **) malloc((START_SERVERS + 1) * sizeof(server_decl_t *)); con_queue = init_queue(START_SERVERS); for (i = 0; i < START_SERVERS; i++) { if ((threads_list[i] = newthread(con_queue)) == NULL) { exit(-1); // FATAL error..... } retcode = ci_thread_create(&thread, (void *(*)(void *)) thread_main, (void *) threads_list[i]); } threads_list[START_SERVERS] = NULL; ci_debug_printf(1, "Threads created ....\n"); retcode = ci_thread_create(&worker_thread, (void *(*)(void *)) worker_main, (void *) (sockfd)); //Listen for events from main server better.............. while (ReadFile(hStdin, &op, 1, &dwRead, NULL)) { printf("Operation Read: %c\n", op); if (op == 'q') goto end_child_main; } ci_thread_join(worker_thread); end_child_main: cancel_all_threads(); exit_normaly(); }
int common_mutex_init(common_mutex_t *mtx, int proc_mtx) { if(proc_mtx) return 0; mtx->isproc = 0; return ci_thread_mutex_init(&mtx->mtx.thread_mutex); }
struct ldap_connections_pool *ldap_pool_create(char *server, int port, char *user, char *password) { struct ldap_connections_pool *pool; ci_thread_mutex_lock(&ldap_connections_pool_mtx); pool = search_ldap_pools(server, port, (user != NULL? user : ""), (password != NULL? password : "")); if(pool) { ci_thread_mutex_unlock(&ldap_connections_pool_mtx); return pool; } pool = malloc(sizeof(struct ldap_connections_pool)); if(!pool) { ci_thread_mutex_unlock(&ldap_connections_pool_mtx); return NULL; } strncpy(pool->server, server, CI_MAXHOSTNAMELEN); pool->server[CI_MAXHOSTNAMELEN]='\0'; pool->port = port; pool->ldapversion = LDAP_VERSION3; pool->next = NULL; if(user) { strncpy(pool->user,user,256); pool->user[255] = '\0'; } else pool->user[0] = '\0'; if(password) { strncpy(pool->password,password,256); pool->password[255] = '\0'; } else pool->password[0] = '\0'; pool->connections = 0; pool->inactive = NULL; pool->used = NULL; snprintf(pool->ldap_uri,1024,"%s://%s:%d","ldap",pool->server,pool->port); pool->ldap_uri[1023] = '\0'; ci_thread_mutex_init(&pool->mutex); #ifdef LDAP_MAX_CONNECTIONS pool->max_connections = 0; ci_thread_cond_init(&pool->pool_cond); #endif add_ldap_pool(pool); ci_thread_mutex_unlock(&ldap_connections_pool_mtx); return pool; }
struct connections_queue *init_queue(int size){ int ret; struct connections_queue *q; if((q=(struct connections_queue *)malloc(sizeof(struct connections_queue)))==NULL) return NULL; ret=ci_thread_mutex_init(&(q->queue_mtx)); ( ret==0&& (ret=ci_thread_mutex_init(&(q->cond_mtx)))); (ret==0 && (ret=ci_thread_cond_init(&(q->queue_cond)))); if(ret==0 && (q->connections=(ci_connection_t *)malloc(size*sizeof(ci_connection_t)))!=NULL){ q->size=size; q->used=0; return q; } //else memory allocation failed or mutex/cond init failed if(q->connections) free(q->connections); free(q); return NULL; }
int postInitImageClassificationService(void) { uint16_t category; ci_thread_rwlock_init(&imageclassify_rwlock); ci_thread_rwlock_wrlock(&imageclassify_rwlock); /*Initialize object pools*/ IMAGEDETECTED_POOL = ci_object_pool_register("image_detected_t", sizeof(image_detected_t) * num_image_categories); if(IMAGEDETECTED_POOL < 0) { ci_debug_printf(1, " srvclassify_init_service: error registering object_pool image_detected_t\n"); ci_thread_rwlock_unlock(&imageclassify_rwlock); return CI_ERROR; } IMAGEDETECTEDCOUNT_POOL = ci_object_pool_register("image_detected_count_t", sizeof(image_detected_count_t) * num_image_categories); if(IMAGEDETECTEDCOUNT_POOL < 0) { ci_debug_printf(1, " srvclassify_init_service: error registering object_pool image_detected_count_t\n"); ci_object_pool_unregister(IMAGEDETECTED_POOL); ci_thread_rwlock_unlock(&imageclassify_rwlock); return CI_ERROR; } if(num_image_categories) { for(category = 0; category < num_image_categories; category++) { if(ci_thread_mutex_init(&imageCategories[category].mutex) != 0) { ci_debug_printf(1, "srv_classify_image: Couldn't init category mutex\n"); } if(ci_thread_cond_init(&imageCategories[category].cond) != 0) { ci_debug_printf(1, "srv_classify_image: Couldn't init category condition lock variable\n"); } } } ci_thread_rwlock_unlock(&imageclassify_rwlock); return CI_OK; }
int ci_txt_template_init(void) { int i; templates = malloc(TEMPLATE_CACHE_SIZE * sizeof(txtTemplate_t)); if(templates == NULL) { ci_debug_printf(1, "Unable to allocate memory in in inittxtTemplate for template storage!\n"); return -1; } for (i = 0; i < TEMPLATE_CACHE_SIZE; i++) { // The following three elements are critical to be cleared, // the rest can be left unintialized templates[i].data = NULL; templates[i].loaded = 0; templates[i].locked = 0; templates[i].must_free = 0; templates[i].non_cached = 0; } txtTemplateInited = 1; ci_thread_mutex_init(&templates_mutex); return 1; }
/*********************************************** Low level functions */ struct stat_area *ci_stat_area_construct(void *mem_block, int size, void (*release_mem)(void *)) { struct stat_area *area = NULL; if (size < ci_stat_memblock_size() ) return NULL; area = malloc(sizeof(struct stat_area)); if (!area) return NULL; assert(((struct stat_memblock *)mem_block)->sig == MEMBLOCK_SIG); ci_thread_mutex_init(&(area->mtx)); area->mem_block = mem_block; area->release_mem = release_mem; area->mem_block->counters64 = mem_block + _CI_ALIGN(sizeof(struct stat_memblock)); area->mem_block->counterskbs = mem_block + _CI_ALIGN(sizeof(struct stat_memblock)) + STAT_INT64.entries_num*sizeof(uint64_t); area->mem_block->counters64_size = STAT_INT64.entries_num; area->mem_block->counterskbs_size = STAT_KBS.entries_num; ci_stat_area_reset(area); return area; }
int init_virusdb() { int ret; unsigned int no = 0; virusdb = malloc(sizeof(struct virus_db)); memset(virusdb, 0, sizeof(struct virus_db)); if (!virusdb) return 0; #ifdef HAVE_LIBCLAMAV_095 if((ret = cl_init(CL_INIT_DEFAULT))) { ci_debug_printf(1, "!Can't initialize libclamav: %s\n", cl_strerror(ret)); return 0; } if(!(virusdb->db = cl_engine_new())) { ci_debug_printf(1, "Clamav DB load: Cannot create new clamav engine\n"); return 0; } if ((ret = cl_load(cl_retdbdir(), virusdb->db, &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB load: cl_load failed: %s\n", cl_strerror(ret)); #elif defined(HAVE_LIBCLAMAV_09X) if ((ret = cl_load(cl_retdbdir(), &(virusdb->db), &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB load: cl_load failed: %s\n", cl_strerror(ret)); #else if ((ret = cl_loaddbdir(cl_retdbdir(), &(virusdb->db), &no))) { ci_debug_printf(1, "cl_loaddbdir: %s\n", cl_perror(ret)); #endif return 0; } #ifdef HAVE_LIBCLAMAV_095 if ((ret = cl_engine_compile(virusdb->db))) { #else if ((ret = cl_build(virusdb->db))) { #endif ci_debug_printf(1, "Database initialization error: %s\n", cl_strerror(ret)); #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(virusdb->db); #else cl_free(virusdb->db); #endif free(virusdb); virusdb = NULL; return 0; } ci_thread_mutex_init(&db_mutex); virusdb->refcount = 1; old_virusdb = NULL; return 1; } /* Instead of using struct virus_db and refcount's someone can use the cl_dup function of clamav library, but it is undocumented so I did not use it. The following implementation we are starting to reload clamav db while threads are scanning for virus but we are not allow any child to start a new scan until we are loading DB. */ /*#define DB_NO_FULL_LOCK 1*/ #undef DB_NO_FULL_LOCK int reload_virusdb() { struct virus_db *vdb = NULL; int ret; unsigned int no = 0; ci_thread_mutex_lock(&db_mutex); if (old_virusdb) { ci_debug_printf(1, "Clamav DB reload pending, cancelling.\n"); ci_thread_mutex_unlock(&db_mutex); return 0; } #ifdef DB_NO_FULL_LOCK ci_thread_mutex_unlock(&db_mutex); #endif vdb = malloc(sizeof(struct virus_db)); if (!vdb) return 0; memset(vdb, 0, sizeof(struct virus_db)); ci_debug_printf(9, "db_reload going to load db\n"); #ifdef HAVE_LIBCLAMAV_095 if(!(vdb->db = cl_engine_new())) { ci_debug_printf(1, "Clamav DB load: Cannot create new clamav engine\n"); return 0; } if ((ret = cl_load(cl_retdbdir(), vdb->db, &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB reload: cl_load failed: %s\n", cl_strerror(ret)); #elif defined(HAVE_LIBCLAMAV_09X) if ((ret = cl_load(cl_retdbdir(), &(vdb->db), &no, CL_DB_STDOPT))) { ci_debug_printf(1, "Clamav DB reload: cl_load failed: %s\n", cl_strerror(ret)); #else if ((ret = cl_loaddbdir(cl_retdbdir(), &(vdb->db), &no))) { ci_debug_printf(1, "Clamav DB reload: cl_loaddbdir failed: %s\n", cl_perror(ret)); #endif return 0; } ci_debug_printf(9, "loaded. Going to build\n"); #ifdef HAVE_LIBCLAMAV_095 if ((ret = cl_engine_compile(vdb->db))) { #else if ((ret = cl_build(vdb->db))) { #endif ci_debug_printf(1, "Clamav DB reload: Database initialization error: %s\n", cl_strerror(ret)); #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(vdb->db); #else cl_free(vdb->db); #endif free(vdb); vdb = NULL; #ifdef DB_NO_FULL_LOCK /*no lock needed */ #else ci_thread_mutex_unlock(&db_mutex); #endif return 0; } ci_debug_printf(9, "Done releasing.....\n"); #ifdef DB_NO_FULL_LOCK ci_thread_mutex_lock(&db_mutex); #endif old_virusdb = virusdb; old_virusdb->refcount--; ci_debug_printf(9, "Old VirusDB refcount:%d\n", old_virusdb->refcount); if (old_virusdb->refcount <= 0) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } virusdb = vdb; virusdb->refcount = 1; ci_thread_mutex_unlock(&db_mutex); return 1; } CL_ENGINE *get_virusdb() { struct virus_db *vdb; ci_thread_mutex_lock(&db_mutex); vdb = virusdb; vdb->refcount++; ci_thread_mutex_unlock(&db_mutex); return vdb->db; } void release_virusdb(CL_ENGINE * db) { ci_thread_mutex_lock(&db_mutex); if (virusdb && db == virusdb->db) virusdb->refcount--; else if (old_virusdb && (db == old_virusdb->db)) { old_virusdb->refcount--; ci_debug_printf(9, "Old VirusDB refcount: %d\n", old_virusdb->refcount); if (old_virusdb->refcount <= 0) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } } else { ci_debug_printf(1, "BUG in srv_clamav service! please contact the author\n"); } ci_thread_mutex_unlock(&db_mutex); } void destroy_virusdb() { if (virusdb) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(virusdb->db); #else cl_free(virusdb->db); #endif free(virusdb); virusdb = NULL; } if (old_virusdb) { #ifdef HAVE_LIBCLAMAV_095 cl_engine_free(old_virusdb->db); #else cl_free(old_virusdb->db); #endif free(old_virusdb); old_virusdb = NULL; } } void set_istag(ci_service_xdata_t * srv_xdata) { char istag[SERVICE_ISTAG_SIZE + 1]; char str_version[64]; char *daily_path; char *s1, *s2; struct cl_cvd *d1; int version = 0, cfg_version = 0; struct stat daily_stat; /*instead of 128 should be strlen("/daily.inc/daily.info")+1*/ daily_path = malloc(strlen(cl_retdbdir()) + 128); if (!daily_path) /*???????? */ return; sprintf(daily_path, "%s/daily.cvd", cl_retdbdir()); if(stat(daily_path,&daily_stat) != 0){ /* if the clamav_lib_path/daily.cvd does not exists */ sprintf(daily_path, "%s/daily.cld", cl_retdbdir()); if(stat(daily_path,&daily_stat) != 0){ /* else try to use the clamav_lib_path/daily.inc/daly.info file instead" */ sprintf(daily_path, "%s/daily.inc/daily.info", cl_retdbdir()); } } if ((d1 = cl_cvdhead(daily_path))) { version = d1->version; free(d1); } free(daily_path); s1 = (char *) cl_retver(); s2 = str_version; while (*s1 != '\0' && s2 - str_version < 64) { if (*s1 != '.') { *s2 = *s1; s2++; } s1++; } *s2 = '\0'; /*cfg_version maybe must set by user when he is changing the srv_clamav configuration.... */ snprintf(istag, SERVICE_ISTAG_SIZE, "-%.3d-%s-%d%d", cfg_version, str_version, cl_retflevel(), version); istag[SERVICE_ISTAG_SIZE] = '\0'; ci_service_set_istag(srv_xdata, istag); }
void child_main(int sockfd, int pipefd) { ci_thread_t thread; int i, ret; signal(SIGTERM, SIG_IGN); /*Ignore parent requests to kill us untill we are up and running */ ci_thread_mutex_init(&threads_list_mtx); ci_thread_mutex_init(&counters_mtx); ci_thread_cond_init(&free_server_cond); ci_stat_attach_mem(child_data->stats, child_data->stats_size, NULL); threads_list = (server_decl_t **) malloc((CONF.THREADS_PER_CHILD + 1) * sizeof(server_decl_t *)); con_queue = init_queue(CONF.THREADS_PER_CHILD); for (i = 0; i < CONF.THREADS_PER_CHILD; i++) { if ((threads_list[i] = newthread(con_queue)) == NULL) { exit(-1); // FATAL error..... } ret = ci_thread_create(&thread, (void *(*)(void *)) thread_main, (void *) threads_list[i]); threads_list[i]->srv_pthread = thread; } threads_list[CONF.THREADS_PER_CHILD] = NULL; /*Now start the listener thread.... */ ret = ci_thread_create(&thread, (void *(*)(void *)) listener_thread, (void *) &sockfd); listener_thread_id = thread; /*set srand for child......*/ srand(((unsigned int)time(NULL)) + (unsigned int)getpid()); /*I suppose that all my threads are up now. We can setup our signal handlers */ child_signals(); /* A signal from parent may comes while we are starting. Listener will not accept any request in this case, (it checks on the beggining of the accept loop for parent commands) so we can shutdown imediatelly even if the parent said gracefuly.*/ if (child_data->father_said) child_data->to_be_killed = IMMEDIATELY; /*start child commands may have non thread safe code but the worker threads does not serving requests yet.*/ commands_execute_start_child(); /*Signal listener to start accepting requests.*/ int doStart = 0; do { ci_thread_mutex_lock(&counters_mtx); doStart = listener_running; ci_thread_mutex_unlock(&counters_mtx); if (!doStart) ci_usleep(5); } while(!doStart); ci_thread_cond_signal(&free_server_cond); while (!child_data->to_be_killed) { char buf[512]; int bytes; if ((ret = ci_wait_for_data(pipefd, 1, wait_for_read)) > 0) { /*data input */ bytes = ci_read_nonblock(pipefd, buf, 511); if (bytes == 0) { ci_debug_printf(1, "Parent closed the pipe connection! Going to term immediately!\n"); child_data->to_be_killed = IMMEDIATELY; } else { buf[bytes] = '\0'; handle_child_process_commands(buf); } } else if (ret < 0) { ci_debug_printf(1, "An error occured while waiting for commands from parent. Terminating!\n"); child_data->to_be_killed = IMMEDIATELY; } if (!listener_running && !child_data->to_be_killed) { ci_debug_printf(1, "Ohh!! something happened to listener thread! Terminating\n"); child_data->to_be_killed = GRACEFULLY; } commands_exec_scheduled(); } ci_debug_printf(5, "Child :%d going down :%s\n", getpid(), child_data->to_be_killed == IMMEDIATELY? "IMMEDIATELY" : "GRACEFULLY"); cancel_all_threads(); commands_execute_stop_child(); exit_normaly(); }
void child_main(int sockfd){ ci_connection_t conn; int claddrlen=sizeof(struct sockaddr_in); ci_thread_t thread; char clientname[300]; int i,retcode,haschild=1,jobs_in_queue=0; int pid=0; child_signals(); pid=getpid(); ci_thread_mutex_init(&threads_list_mtx); ci_thread_mutex_init(&counters_mtx); ci_thread_cond_init(&free_server_cond); threads_list=(server_decl_t **)malloc((START_SERVERS+1)*sizeof(server_decl_t *)); con_queue=init_queue(START_SERVERS); for(i=0;i<START_SERVERS;i++){ if((threads_list[i]=newthread(con_queue))==NULL){ exit(-1);// FATAL error..... } retcode=ci_thread_create(&thread,(void *(*)(void *))thread_main,(void *)threads_list[i]); } threads_list[START_SERVERS]=NULL; for(;;){ //Global for if(!ci_proc_mutex_lock(&accept_mutex)){ if(errno==EINTR){ debug_printf(5,"EINTR received\n"); if(child_data->to_be_killed) goto end_child_main; continue; } } child_data->idle=0; debug_printf(7,"Child %d getting requests now ...\n",pid); do{//Getting requests while we have free servers..... do{ errno = 0; if(((conn.fd = accept(sockfd, (struct sockaddr *)&(conn.claddr), &claddrlen)) == -1) && errno != EINTR){ debug_printf(1,"error accept .... %d\nExiting server ....\n",errno); exit(-1); //For the moment ....... goto end_child_main ; } if(errno==EINTR && child_data->to_be_killed) goto end_child_main; }while(errno==EINTR); getsockname(conn.fd,(struct sockaddr *)&(conn.srvaddr),&claddrlen); icap_socket_opts(sockfd); if((jobs_in_queue=put_to_queue(con_queue,&conn))==0){ debug_printf(1,"ERROR!!!!!!NO AVAILABLE SERVERS!!!!!!!!!\n"); child_data->to_be_killed=GRACEFULLY; debug_printf(1,"Jobs in Queue:%d,Free servers:%d, Used Servers :%d, Requests %d\n", jobs_in_queue, child_data->freeservers,child_data->usedservers,child_data->requests); goto end_child_main; } ci_thread_mutex_lock(&counters_mtx); haschild=(child_data->freeservers?1:0); ci_thread_mutex_unlock(&counters_mtx); (child_data->connections)++; //NUM of Requests.... }while(haschild); child_data->idle=1; ci_proc_mutex_unlock(&accept_mutex); ci_thread_mutex_lock(&counters_mtx); if(child_data->freeservers==0){ debug_printf(7,"Child %d waiting for a thread to accept more connections ...\n",pid); ci_thread_cond_wait(&free_server_cond,&counters_mtx); } ci_thread_mutex_unlock(&counters_mtx); } end_child_main: cancel_all_threads(); exit_normaly(); }
int main(int argc, char **argv){ int i,fd,len; struct buffer buf; char *str; FILE *f; if(argc<4){ printf("Usage:\n%s servername theadsnum max_requests file1 file2 .....\n",argv[0]); exit(1); } signal(SIGPIPE,SIG_IGN); signal(SIGINT, sigint_handler); time(&START_TIME); srand((int)START_TIME); servername=argv[1]; threadsnum=atoi(argv[2]); if(threadsnum<=0) return 0; if((MAX_REQUESTS=atoi(argv[3]))<0) MAX_REQUESTS=0; threads=malloc(sizeof(ci_thread_t)*threadsnum); for(i=0;i<threadsnum;i++) threads[i]=0; if(argc>4){ // FILES=argv+3; FILES_NUMBER=argc-3; ci_thread_mutex_init(&filemtx); ci_thread_mutex_init(&statsmtx); printf("Files to send:%d\n",FILES_NUMBER); for(i=0;i<threadsnum;i++){ printf("Create thread %d\n",i); ci_thread_create(&(threads[i]),threadjobsendfiles,NULL); // sleep(1); } } else{ //Construct reqmod...... buf.buf=malloc(1024*sizeof(char)); buildreqheaders(buf.buf); buf.size=strlen(buf.buf); for(i=0;i<threadsnum;i++){ printf("Create thread %d\n",i); ci_thread_create(&(threads[i]),threadjobreqmod,(void *)&buf); sleep(1); } } while(1){ sleep(1); if(MAX_REQUESTS && requests_stats>=MAX_REQUESTS){ printf("Oops max requests reached. Exiting .....\n"); _THE_END=1; break; } print_stats(); } for(i=0;i<threadsnum;i++){ ci_thread_join(threads[i]); } print_stats(); ci_thread_mutex_destroy(&filemtx); ci_thread_mutex_destroy(&statsmtx); }
int main(int argc, char **argv) { int i; if (argc < 4) { printf ("Usage:\n%s servername service threadsnum max_requests file1 file2 .....\n", argv[0]); exit(1); } signal(SIGPIPE, SIG_IGN); signal(SIGINT, sigint_handler); time(&START_TIME); srand((int) START_TIME); servername = argv[1]; service = argv[2]; threadsnum = atoi(argv[3]); if (threadsnum <= 0) return 0; if ((MAX_REQUESTS = atoi(argv[4])) < 0) MAX_REQUESTS = 0; threads = malloc(sizeof(ci_thread_t) * threadsnum); if (!threads) { ci_debug_printf(1, "Error allocation memory for threads array\n"); exit(-1); } for (i = 0; i < threadsnum; i++) threads[i] = 0; if (argc > 4) { // FILES = argv + 4; FILES_NUMBER = argc - 4; ci_thread_mutex_init(&filemtx); ci_thread_mutex_init(&statsmtx); printf("Files to send:%d\n", FILES_NUMBER); for (i = 0; i < threadsnum; i++) { printf("Create thread %d\n", i); ci_thread_create(&(threads[i]), (void *(*)(void *)) threadjobsendfiles, NULL); // sleep(1); } } else { //Construct reqmod...... exit(-1); for (i = 0; i < threadsnum; i++) { printf("Create thread %d\n", i); ci_thread_create(&(threads[i]), (void *(*)(void *)) threadjobreqmod, (void *) NULL /*data*/); sleep(1); } } while (1) { sleep(1); if (MAX_REQUESTS && requests_stats >= MAX_REQUESTS) { printf("Oops max requests reached. Exiting .....\n"); _THE_END = 1; break; } print_stats(); } for (i = 0; i < threadsnum; i++) { ci_thread_join(threads[i]); printf("Thread %d exited\n", i); } print_stats(); ci_thread_mutex_destroy(&filemtx); ci_thread_mutex_destroy(&statsmtx); return 0; }
int start_server() { #ifdef MULTICHILD int child_indx, i; HANDLE child_handle; ci_thread_t mon_thread; int childs, freeservers, used, maxrequests; ci_proc_mutex_init(&accept_mutex); ci_thread_mutex_init(&control_process_mtx); if (!create_childs_queue(&childs_queue, MAX_CHILDS)) { log_server(NULL, "Can't init shared memory.Fatal error, exiting!\n"); ci_debug_printf(1, "Can't init shared memory.Fatal error, exiting!\n"); exit(0); } for (i = 0; i < START_CHILDS + 2; i++) { child_handle = start_child(LISTEN_SOCKET); } /*Start died childs monitor thread*/ /* ci_thread_create(&mon_thread, (void *(*)(void *))wait_achild_to_die, (void *)NULL); */ while (1) { if (check_for_died_child(5000)) continue; // Sleep(5000); childs_queue_stats(&childs_queue, &childs, &freeservers, &used, &maxrequests); ci_debug_printf(1, "Server stats: \n\t Childs:%d\n\t Free servers:%d\n\tUsed servers:%d\n\tRequests served:%d\n", childs, freeservers, used, maxrequests); if ((freeservers <= MIN_FREE_SERVERS && childs < MAX_CHILDS) || childs < START_CHILDS) { ci_debug_printf(1, "Going to start a child .....\n"); child_handle = start_child(LISTEN_SOCKET); } else if (freeservers >= MAX_FREE_SERVERS && childs > START_CHILDS) { ci_thread_mutex_lock(&control_process_mtx); if ((child_indx = find_an_idle_child(&childs_queue)) < 0) continue; childs_queue.childs[child_indx].to_be_killed = GRACEFULLY; tell_child_to_die(childs_queue.childs[child_indx].pipe); ci_thread_mutex_unlock(&control_process_mtx); ci_debug_printf(1, "Going to stop child %d .....\n", childs_queue.childs[child_indx].pid); } } /* for(i=0;i<START_CHILDS;i++){ pid=wait(&status); ci_debug_printf(1,"The child %d died with status %d\n",pid,status); } */ #else child_data = (child_shared_data_t *) malloc(sizeof(child_shared_data_t)); child_data->pid = 0; child_data->freeservers = START_SERVERS; child_data->usedservers = 0; child_data->requests = 0; child_data->connections = 0; child_data->to_be_killed = 0; child_data->idle = 1; child_main(LISTEN_SOCKET); #endif return 1; }
int init_ldap_pools() { ldap_pools = NULL; ci_thread_mutex_init(&ldap_connections_pool_mtx); return 1; }