/** * 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; }
/** * 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); }