Exemple #1
0
/**
 * Destroys the worker structures. 
 */
void worker_destroy()
{
	int i,sval=0;
	if (callbacks){
		while(callbacks->head)
			cb_remove(callbacks->head);
		shm_free(callbacks);
	}

	// to deny runing the poison queue again
	config->workers = 0;
	if (tasks) {
	//	LOG(L_CRIT,"-1-\n");
		lock_get(tasks->lock);
		for(i=0;i<tasks->max;i++){
			if (tasks->queue[i].msg) AAAFreeMessage(&(tasks->queue[i].msg));
			tasks->queue[i].msg = 0;
			tasks->queue[i].p = 0;
		}
		lock_release(tasks->lock);

		LOG(L_INFO,"Unlocking workers waiting on empty queue...\n");
		for(i=0;i<config->workers;i++)
			sem_release(tasks->empty);
		LOG(L_INFO,"Unlocking workers waiting on full queue...\n");
		i=0;
		while(sem_getvalue(tasks->full,&sval)==0)			
			if (sval<=0) {
				sem_release(tasks->full);
				i=1;
			}
			else break;
		sleep(i);
		
		lock_get(tasks->lock);
	//	LOG(L_CRIT,"-2-\n");	
		shm_free(tasks->queue);
		lock_destroy(tasks->lock);
		lock_dealloc((void*)tasks->lock);
	//	LOG(L_CRIT,"-3-\n");	
		
		//lock_release(tasks->empty);
		sem_free(tasks->full);
		sem_free(tasks->empty);
		
		shm_free(tasks);
	}
}
/**
 * Send a AAAMessage synchronously.
 * This blocks until a response is received or a transactional time-out happens. 
 * @param message - the request to be sent
 * @param peer_id - FQDN of the peer to send
 * @returns 1 on success, 0 on failure 
 * \todo remove peer_id and add Realm routing
 * \todo replace the busy-waiting lock in here with one that does not consume CPU
 */
AAAMessage* AAASendRecvMessageToPeer(AAAMessage *message, str *peer_id)
{
	peer *p;
	gen_sem_t *sem;
	cdp_trans_t *t;
	AAAMessage *ans;
	
	p = get_peer_by_fqdn(peer_id);
	if (!p) {
		LOG(L_ERR,"ERROR:AAASendRecvMessageToPeer(): Peer unknown %.*s\n",peer_id->len,peer_id->s);
		goto error;
	}
	if (p->state!=I_Open && p->state!=R_Open){
		LOG(L_ERR,"ERROR:AAASendRecvMessageToPeer(): Peer not connected to %.*s\n",peer_id->len,peer_id->s);
		goto error;
	}
	
	
	if (is_req(message)){
		sem_new(sem,0);
		t = cdp_add_trans(message,sendrecv_cb,(void*)sem,config->transaction_timeout,0);

//		if (!peer_send_msg(p,message)) {
		if (!sm_process(p,Send_Message,message,0,0)){	
			sem_free(sem);				
			goto error;
		}

		/* block until callback is executed */
		while(sem_get(sem)<0){
			if (shutdownx&&(*shutdownx)) goto error;
			LOG(L_WARN,"WARN:AAASendRecvMessageToPeer(): interrupted by signal or something > %s\n",strerror(errno));
		}
		sem_free(sem);		
		ans = t->ans;
		cdp_free_trans(t);
		return ans;
	} else {
		LOG(L_ERR,"ERROR:AAASendRecvMessageToPeer(): can't add wait for answer to answer.\n");
		goto error;
	}

		
error:	
out_of_memory:
	AAAFreeMessage(&message);
	return 0;
}
Exemple #3
0
/**
 * Initializes the worker structures, like the task queue.
 */
void worker_init()
{
	tasks = shm_malloc(sizeof(task_queue_t));
	
	tasks->lock = lock_alloc();
	tasks->lock = lock_init(tasks->lock);
	
	sem_new(tasks->empty,0);
		
	sem_new(tasks->full,1);
		
	tasks->start = 0;
	tasks->end = 0;
	tasks->max = config->queue_length;
	tasks->queue = shm_malloc(tasks->max*sizeof(task_t));
	if (!tasks->queue) {
		LOG_NO_MEM("shm",tasks->max*sizeof(task_t));
		goto out_of_memory;
	}
	memset(tasks->queue,0,tasks->max*sizeof(task_t));
		
	callbacks = shm_malloc(sizeof(cdp_cb_list_t));
	if (!callbacks) goto out_of_memory;
	callbacks->head = 0; 
	callbacks->tail = 0;
	return;
out_of_memory:
	if (tasks){
		if (tasks->lock) {
			lock_destroy(tasks->lock);
			lock_dealloc(&(tasks->lock)); 
		}
		sem_free(tasks->full);
		sem_free(tasks->empty);
		if (tasks->queue) shm_free(tasks->queue);
		shm_free(tasks);
	}
	if (callbacks) shm_free(callbacks);
}