Ejemplo n.º 1
0
int wait_for_queue(struct connections_queue *q){
     ci_debug_printf(7,"Waiting for a request....\n");
     if(ci_thread_mutex_lock(&(q->cond_mtx))!=0)
	  return -1;
     if(ci_thread_cond_wait(&(q->queue_cond),&(q->cond_mtx))!=0){
	  ci_thread_mutex_unlock(&(q->cond_mtx));
	  return -1;
     }
     if(ci_thread_mutex_unlock(&(q->cond_mtx))!=0)
	  return -1;
     return 1;
}
LinkedCascade *getFreeCascade(ImageCategory *category)
{
LinkedCascade *item = NULL;
	if(category->freeing_category) return NULL;

	ci_thread_mutex_lock(&category->mutex);
	while(!category->free_cascade)
	{
		ci_thread_cond_wait(&category->cond, &category->mutex);
	}

	// Ok, we should have a free cascade:
	// Remove free cascade item from free list
	item = category->free_cascade;
	category->free_cascade = item->next;

	ci_thread_mutex_unlock(&category->mutex);
return item; // Tell caller the cascade
}
Ejemplo n.º 3
0
void listener_thread(int *fd)
{
     ci_connection_t conn;
     socklen_t claddrlen = sizeof(struct sockaddr_in);
     int haschild = 1, jobs_in_queue = 0;
     int pid, sockfd;
     sockfd = *fd;
     thread_signals(1);
     /*Wait main process to signal us to start accepting requests*/
     ci_thread_mutex_lock(&counters_mtx);
     listener_running = 1;
     ci_thread_cond_wait(&free_server_cond, &counters_mtx);
     ci_thread_mutex_unlock(&counters_mtx);
     pid = getpid();
     for (;;) {                 //Global for
          if (child_data->to_be_killed) {
               ci_debug_printf(5, "Listener of pid:%d exiting!\n", pid);
               goto LISTENER_FAILS_UNLOCKED;
          }
          if (!ci_proc_mutex_lock(&accept_mutex)) {
               if (errno == EINTR) {
                    ci_debug_printf(5,
                                    "proc_mutex_lock interrupted (EINTR received, pid=%d)!\n",
                                    pid);
                    /*Try again to take the lock */
                    continue;
               }
               else {
                    ci_debug_printf(1,
                                    "Unknown errno %d in proc_mutex_lock of pid %d. Exiting!\n",
                                    errno, pid);
                    goto LISTENER_FAILS_UNLOCKED;
               }
          }
          child_data->idle = 0;
          ci_debug_printf(7, "Child %d getting requests now ...\n", pid);
          do {                  //Getting requests while we have free servers.....
#ifndef SINGLE_ACCEPT
               fd_set fds;
               int ret;
               do {
                    FD_ZERO(&fds);
                    FD_SET(sockfd, &fds);
                    errno = 0;
                    ret = select(sockfd + 1, &fds, NULL, NULL, NULL);
                    if (ret < 0) {
                         if (errno != EINTR) {
                              ci_debug_printf(1,
                                              "Error in select %d! Exiting server!\n",
                                              errno);
                              goto LISTENER_FAILS;
                         }
                         if (child_data->to_be_killed) {
                              ci_debug_printf(5,
                                              "Listener server signalled to exit!\n");
                              goto LISTENER_FAILS;
                         }
                    }
               } while (errno == EINTR);
#endif
               do {
                    errno = 0;
                    claddrlen = sizeof(conn.claddr.sockaddr);
                    if (((conn.fd =
                          accept(sockfd,
                                 (struct sockaddr *) &(conn.claddr.sockaddr),
                                 &claddrlen)) == -1)) {
                         if (errno != EINTR) {
                              ci_debug_printf(1,
                                              "Error accept %d!\nExiting server!\n",
                                              errno);
                              goto LISTENER_FAILS;
                         }
                         /*Here we are going to exit only if accept interrupted by a signal
                           else if we accepted an fd we must add it to queue for 
                           processing. */
                         if (errno == EINTR && child_data->to_be_killed) {
                              ci_debug_printf(5,
                                              "Listener server signalled to exit!\n");
                              goto LISTENER_FAILS;
                         }
                    }
               } while (errno == EINTR && !child_data->to_be_killed);
               claddrlen = sizeof(conn.srvaddr.sockaddr);
               getsockname(conn.fd,
                           (struct sockaddr *) &(conn.srvaddr.sockaddr),
                           &claddrlen);
               ci_fill_sockaddr(&conn.claddr);
               ci_fill_sockaddr(&conn.srvaddr);

               icap_socket_opts(sockfd, MAX_SECS_TO_LINGER);

               if ((jobs_in_queue = put_to_queue(con_queue, &conn)) == 0) {
                    ci_debug_printf(1,
                                    "ERROR!!!!!! NO AVAILABLE SERVERS! THIS IS A BUG!!!!!!!!\n");
                    ci_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 LISTENER_FAILS;
               }
               (child_data->connections)++;     //NUM of Requests....

               if (child_data->to_be_killed) {
                   ci_debug_printf(5, "Listener server must exit!\n");
                   goto LISTENER_FAILS;
               }
               ci_thread_mutex_lock(&counters_mtx);
               haschild =
                   ((child_data->freeservers - jobs_in_queue) > 0 ? 1 : 0);
               ci_thread_mutex_unlock(&counters_mtx);
          } while (haschild);
          ci_debug_printf(7, "Child %d STOPS getting requests now ...\n", pid);
          child_data->idle = 1;
          while (!ci_proc_mutex_unlock(&accept_mutex)) {
               if (errno != EINTR) {
                    ci_debug_printf(1,
                                    "Error:%d while trying to unlock proc_mutex, exiting listener of server:%d\n",
                                    errno, pid);
                    goto LISTENER_FAILS_UNLOCKED;
               }
               ci_debug_printf(5,
                               "Mutex lock interrupted while trying to unlock proc_mutex, pid: %d\n",
                               pid);
          }

          ci_thread_mutex_lock(&counters_mtx);
          if ((child_data->freeservers - connections_pending(con_queue)) <= 0) {
               ci_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);
     }
   LISTENER_FAILS_UNLOCKED:
     listener_running = 0;
     return;

   LISTENER_FAILS:
     listener_running = 0;
     errno = 0;
     while (!ci_proc_mutex_unlock(&accept_mutex)) {
          if (errno != EINTR) {
               ci_debug_printf(1,
                               "Error:%d while trying to unlock proc_mutex of server:%d\n",
                               errno, pid);
               break;
          }
          ci_debug_printf(7,
                          "Mutex lock interrupted while trying to unlock proc_mutex before terminating\n");
     }
     return;
}
Ejemplo n.º 4
0
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();
}
Ejemplo n.º 5
0
int worker_main(ci_socket sockfd)
{
     ci_connection_t conn;
     int claddrlen = sizeof(struct sockaddr_in);
//     char clientname[300];
     int haschild = 1, jobs_in_queue = 0;
     int pid = 0, error;


     for (;;) {                 //Global for
          if (!ci_proc_mutex_lock(&accept_mutex)) {
               if (child_data->to_be_killed)
                    return 1;
               continue;
          }
          child_data->idle = 0;
          pid = (int) child_data->pid;
          ci_debug_printf(1, "Child %d getting requests now ...\n", pid);

          do {                  //Getting requests while we have free servers.....
               ci_debug_printf(1, "In accept loop..................\n");
               error = 0;
               if (((conn.fd =
                     accept(sockfd, (struct sockaddr *) &(conn.claddr.sockaddr),
                            &claddrlen)) == INVALID_SOCKET) &&
//             if(((conn.fd = WSAAccept(sockfd, (struct sockaddr *)&(conn.claddr), &claddrlen,NULL,NULL)) == INVALID_SOCKET ) && 
                   (error = WSAGetLastError())) {
                    ci_debug_printf(1,
                                    "error accept .... %d\nExiting server ....\n",
                                    error);
                    exit(-1);   //For the moment .......
               }

               ci_debug_printf(1, "Accepting one connection...\n");
               claddrlen = sizeof(conn.srvaddr.sockaddr);
               getsockname(conn.fd,
                           (struct sockaddr *) &(conn.srvaddr.sockaddr),
                           &claddrlen);

               ci_fill_sockaddr(&conn.claddr);
               ci_fill_sockaddr(&conn.srvaddr);

               icap_socket_opts(sockfd, MAX_SECS_TO_LINGER);

               if ((jobs_in_queue = put_to_queue(con_queue, &conn)) == 0) {
                    ci_debug_printf(1,
                                    "ERROR!!!!!!NO AVAILABLE SERVERS!!!!!!!!!\n");
//                  child_data->to_be_killed=GRACEFULLY;
                    ci_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);
               }
               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) {
               ci_debug_printf(1,
                               "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);

     }

}
Ejemplo n.º 6
0
LDAP *ldap_connection_open(struct ldap_connections_pool *pool)
{
    struct ldap_connection *conn;
    struct berval ldap_passwd, *servercred;
    int ret;
    char *ldap_user;
    if (ci_thread_mutex_lock(&pool->mutex)!=0)
        return NULL;
#ifdef LDAP_MAX_CONNECTIONS
    do {
#endif
        if (pool->inactive) {
            conn = pool->inactive;
            pool->inactive = pool->inactive->next;

            conn->next = pool->used;
            pool->used = conn;
            conn->hits++;
            ci_thread_mutex_unlock(&pool->mutex);
            return conn->ldap;
        }
#ifdef LDAP_MAX_CONNECTIONS
        if (pool->connections >= pool->max_connections) {
            /*wait for an ldap connection to be released. The condwait will unlock
              pool->mutex */
            if (ci_thread_cond_wait(&(pool->pool_cond), &(pool->mutex)) != 0) {
                ci_thread_mutex_unlock(&(pool->mutex));
                return NULL;
            }
        }
    } while(pool->connections >= pool->max_connections);
#else
        ci_thread_mutex_unlock(&pool->mutex);
#endif


    conn=malloc(sizeof(struct ldap_connection));
    if (!conn) {
#ifdef LDAP_MAX_CONNECTIONS
        ci_thread_mutex_unlock(&pool->mutex);
#endif
        return NULL;
    }
    conn->hits = 1;

    ret = ldap_initialize(&conn->ldap, pool->ldap_uri);
    if (!conn->ldap) {
#ifdef LDAP_MAX_CONNECTIONS
        ci_thread_mutex_unlock(&pool->mutex);
#endif
        ci_debug_printf(1, "Error allocating memory for ldap connection: %s!\n",
                        ldap_err2string(ret));
        free(conn);
        return NULL;
    }

    ldap_set_option(conn->ldap, LDAP_OPT_PROTOCOL_VERSION, &(pool->ldapversion));
    if (pool->user[0] != '\0')
        ldap_user = pool->user;
    else
        ldap_user = NULL;

    if (pool->password[0] != '\0') {
        ldap_passwd.bv_val = pool->password;
        ldap_passwd.bv_len = strlen(pool->password);
    }
    else {
        ldap_passwd.bv_val = NULL;
        ldap_passwd.bv_len = 0;
    }

    ret = ldap_sasl_bind_s( conn->ldap,
                            ldap_user,
                            LDAP_SASL_SIMPLE,
                            &ldap_passwd,
                            NULL,
                            NULL,
                            &servercred );

    if (ret != LDAP_SUCCESS) {
        ci_debug_printf(1, "Error bind to ldap server: %s!\n",ldap_err2string(ret));
#ifdef LDAP_MAX_CONNECTIONS
        ci_thread_mutex_unlock(&pool->mutex);
#endif
        ldap_unbind_ext_s(conn->ldap, NULL, NULL);
        free(conn);
        return NULL;
    }
    if(servercred) {
        ber_bvfree(servercred);
    }

#ifdef LDAP_MAX_CONNECTIONS
    /*we are already locked*/
#else
    if (ci_thread_mutex_lock(&pool->mutex)!= 0) {
        ci_debug_printf(1, "Error locking mutex while opening ldap connection!\n");
        ldap_unbind_ext_s(conn->ldap, NULL, NULL);
        free(conn);
        return NULL;
    }
#endif
    pool->connections++;
    conn->next = pool->used;
    pool->used = conn;
    ci_thread_mutex_unlock(&pool->mutex);
    return conn->ldap;
}