int event_queue_push(event_level_t level, struct connectSock * psock, event_queue_pt pt, // uint8_t cmd, // uint16_t opt_code, void * pdata, int siz) { int ret = 0; //int max_conn = 0; uint32_t weight = 0; struct cmd_event * pe; event_queue_t * peq; uint16_t * p_value; timestamp++; //printf("\ntimestamp = %u\n", timestamp); if (siz > MAX_EBUF_SIZ) { log_error(LOG_NOTICE, "MAX_EBUF_SIZ"); return -1; } weight = ++weightness; if (psock != NULL) { weight = psock->addr; p_value = &psock->event_cnt; } else { p_value = &pserial_des->event_cnt; } peq = pq + get_tindex(weight); //平衡相应的队列 EVENT_LOCK(peq); debug_event("\nstart push ok line = %d\n", __LINE__); do { pe = cmd_event_new(peq, siz); if (pe == NULL) { if (psock == NULL) { peq = pq + get_tindex(weight + 1); pe = cmd_event_new(peq, siz); } if (pe == NULL) { ret = -1; log_error(LOG_NOTICE, "cmd queue full queue.no = %d", peq->queue_no); break; } } pe->level = level; // pe->cmd = cmd; // pe->opt_code = opt_code; pe->weight_value = ++(*p_value); pe->timestamp = timestamp; pe->cb = pt; pe->psock = psock; memcpy(pe->buffer, pdata, siz); //printf("\npe->level = %d, pe->timestamp = %u\n",level, timestamp); if (min_heap_insert(peq->heap, pe) == NULL) { log_error(LOG_ERROR, "min_heap_inisert !!!!"); cmd_event_del(peq, pe); } } while (0); // printf("\nccc\n"); event_queue_wakeup(peq); debug_event("\nend push ok line = %d\n", __LINE__); EVENT_UNLOCK(peq); return ret; }
static int handle_cmd(il_octet_string_t *event, long offset) { char *job_id_s; struct event_queue *eq; int num_replies, num_threads = 0; int timeout, result; long receipt; struct timespec endtime; struct timeval tv; /* parse command */ if(parse_cmd(event->data, &job_id_s, &receipt, &timeout) < 0) return(0); #if defined(INTERLOGD_FLUSH) glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, "received FLUSH command"); /* catchup with all neccessary event files */ if(job_id_s) { struct event_store *es = event_store_find(job_id_s, NULL); if(es == NULL) { goto cmd_error; } result = event_store_recover(es); /* NOTE: if flush had been stored in file, there would have been no need to lock the event_store at all */ event_store_release(es); if(result < 0) { glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, " error trying to catch up with event file: %s", error_get_msg()); clear_error(); } } else /* this call does not fail :-) */ event_store_recover_all(); glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, " alerting threads to report status"); /* prevent threads from reporting too early */ if(pthread_mutex_lock(&flush_lock) < 0) { /*** this error is considered too serious to allow the program run anymore! set_error(IL_SYS, errno, "pthread_mutex_lock: error locking flush lock"); goto cmd_error; */ abort(); } /* wake up all threads */ if(job_id_s) { /* find appropriate queue */ eq = queue_list_get(job_id_s); if(eq == NULL) goto cmd_error; if(!event_queue_empty(eq) && !queue_list_is_log(eq)) { num_threads++; event_queue_cond_lock(eq); eq->flushing = 1; event_queue_wakeup(eq); event_queue_cond_unlock(eq); } } else { /* iterate over event queues */ for(eq=queue_list_first(); eq != NULL; eq=queue_list_next()) { if(!event_queue_empty(eq) && !queue_list_is_log(eq)) { num_threads++; event_queue_cond_lock(eq); eq->flushing = 1; event_queue_wakeup(eq); event_queue_cond_unlock(eq); } } } if(!bs_only) { eq = queue_list_get(NULL); if(eq == NULL) goto cmd_error; if(!event_queue_empty(eq)) { num_threads++; event_queue_cond_lock(eq); eq->flushing = 1; event_queue_wakeup(eq); event_queue_cond_unlock(eq); } } /* wait for thread replies */ num_replies = 0; result = 1; gettimeofday(&tv, NULL); endtime.tv_sec = tv.tv_sec + timeout; endtime.tv_nsec = 1000 * tv.tv_usec; while(num_replies < num_threads) { int ret; if((ret=pthread_cond_timedwait(&flush_cond, &flush_lock, &endtime)) < 0) { char buf[256]; il_strerror_r(errno, buf, sizeof(buf)); glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, " error waiting for thread reply: %s", buf); result = (ret == ETIMEDOUT) ? 0 : -1; break; } /* collect results from reporting threads */ if(job_id_s) { /* find appropriate queue */ eq = queue_list_get(job_id_s); if(eq == NULL) goto cmd_error; if(!queue_list_is_log(eq)) { event_queue_cond_lock(eq); if(eq->flushing == 2) { eq->flushing = 0; num_replies++; result = ((result == 1) || (eq->flush_result < 0)) ? eq->flush_result : result; } event_queue_cond_unlock(eq); } } else { /* iterate over event queues */ for(eq=queue_list_first(); eq != NULL; eq=queue_list_next()) { if(!queue_list_is_log(eq)) { event_queue_cond_lock(eq); if(eq->flushing == 2) { eq->flushing = 0; num_replies++; glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_DEBUG, " thread reply: %d", eq->flush_result); result = ((result == 1) || (eq->flush_result < 0)) ? eq->flush_result : result; } event_queue_cond_unlock(eq); } } } if(!bs_only) { eq = queue_list_get(NULL); if(eq == NULL) goto cmd_error; event_queue_cond_lock(eq); if(eq->flushing == 2) { eq->flushing = 0; num_replies++; result = ((result == 1) || (eq->flush_result < 0)) ? eq->flush_result : result; } event_queue_cond_unlock(eq); } } /* prevent deadlock in next flush */ if(pthread_mutex_unlock(&flush_lock) < 0) abort(); /* report back to local logger */ switch(result) { case 1: result = 0; break; case 0: result = EDG_WLL_IL_EVENTS_WAITING; break; default: result = EDG_WLL_IL_SYS; break; } if(job_id_s) free(job_id_s); result = send_confirmation(receipt, result); if(result <= 0) glite_common_log(IL_LOG_CATEGORY, LOG_PRIORITY_ERROR, "handle_cmd: error sending status: %s", error_get_msg()); return(1); cmd_error: if(job_id_s) free(job_id_s); return(-1); #else return(0); #endif /* INTERLOGD_FLUSH */ }