/* write handler */ int conn_write_handler(CONN *conn) { int ret = -1, n = 0; CONN_CHECK_RET(conn, ret); CHUNK *cp = NULL; if(conn && conn->send_queue && QTOTAL(conn->send_queue) > 0) { DEBUG_LOGGER(conn->logger, "Ready for send data to %s:%d via %d " "qtotal:%d qhead:%d qcount:%d", conn->ip, conn->port, conn->fd, QTOTAL(conn->send_queue), QHEAD(conn->send_queue), QCOUNT(conn->send_queue)); if(QUEUE_HEAD(conn->send_queue, PCHUNK, &cp) == 0) { DEBUG_LOGGER(conn->logger, "Ready for send data to %s:%d via %d qtotal:%d pcp:%08x", conn->ip, conn->port, conn->fd, QTOTAL(conn->send_queue), cp); if((n = CHUNK_WRITE(cp, conn->fd)) > 0) { conn->sent_data_total += n; DEBUG_LOGGER(conn->logger, "Sent %d byte(s) (total sent %lld) " "to %s:%d via %d leave %lld", n, conn->sent_data_total, conn->ip, conn->port, conn->fd, CK_LEFT(cp)); /* CONN TIMER sample */ TIMER_SAMPLE(conn->timer); if(CHUNK_STATUS(cp) == CHUNK_STATUS_OVER ) { if(QUEUE_POP(conn->send_queue, PCHUNK, &cp) == 0) { DEBUG_LOGGER(conn->logger, "Completed chunk[%08x] and clean it leave %d", cp, QTOTAL(conn->send_queue)); CK_CLEAN(cp); } } ret = 0; } else { FATAL_LOGGER(conn->logger, "Sending data to %s:%d via %d failed, %s", conn->ip, conn->port, conn->fd, strerror(errno)); /* Terminate connection */ CONN_TERMINATE(conn); } } if(QTOTAL(conn->send_queue) <= 0) { conn->event->del(conn->event, E_WRITE); } } return ret; }
/* push chunk file */ int conn_push_file(CONN *conn, char *filename, long long offset, long long size) { int ret = -1; CHUNK *cp = NULL; CONN_CHECK_RET(conn, ret); if(conn && conn->send_queue && filename && offset >= 0 && size > 0) { CK_INIT(cp); if(cp) { CK_FILE(cp, filename, offset, size); QUEUE_PUSH(conn->send_queue, PCHUNK, &cp); if((QTOTAL(conn->send_queue)) > 0 ) conn->event->add(conn->event, E_WRITE); DEBUG_LOGGER(conn->logger, "Pushed file[%s] [%lld][%lld] to " "send_queue total %d on %s:%d via %d ", filename, offset, size, QTOTAL(conn->send_queue), conn->ip, conn->port, conn->fd); ret = 0; } } return ret; }
/* push chunk */ int conn_push_chunk(CONN *conn, void *data, int size) { int ret = -1; CHUNK *cp = NULL; CONN_CHECK_RET(conn, ret); if(conn && conn->send_queue && data && size > 0) { CK_INIT(cp); if(cp) { CK_MEM(cp, size); CK_MEM_COPY(cp, data, size); QUEUE_PUSH(conn->send_queue, PCHUNK, &cp); } if(QTOTAL(conn->send_queue) > 0 ) conn->event->add(conn->event, E_WRITE); DEBUG_LOGGER(conn->logger, "Pushed chunk size[%d] to send_queue " "total %d on %s:%d via %d ", size, QTOTAL(conn->send_queue), conn->ip, conn->port, conn->fd); ret = 0; } return ret; }
/* run procthread */ void procthread_run(void *arg) { PROCTHREAD *pth = (PROCTHREAD *)arg; if(pth) { pth->running_status = 1; while(pth->running_status) { if(QTOTAL(pth->message_queue) > 0) message_handler(pth->message_queue, pth->logger); usleep(pth->usec_sleep); } } #ifdef HAVE_PTHREAD pthread_exit(NULL); #endif }
/* Add connection message */ int procthread_addconn(PROCTHREAD *pth, CONN *conn) { MESSAGE msg = {0}; int ret = -1; if(pth && pth->message_queue && conn) { msg.msg_id = MESSAGE_NEW_SESSION; msg.fd = conn->fd; msg.handler = (void *)conn; msg.parent = (void *)pth; QUEUE_PUSH(pth->message_queue, MESSAGE, &msg); DEBUG_LOGGER(pth->logger, "Ready for adding msg[%s] connection[%s:%d] via %d total %d", MESSAGE_DESC(MESSAGE_NEW_SESSION), conn->ip, conn->port, conn->fd, QTOTAL(pth->message_queue)); ret = 0; } return ret; }
/* add new transaction */ int procthread_newtransaction(PROCTHREAD *pth, CONN *conn, int tid) { MESSAGE msg = {0}; int ret = -1; if(pth && pth->message_queue && conn) { msg.msg_id = MESSAGE_TRANSACTION; msg.fd = conn->fd; msg.tid = tid; msg.handler = conn; msg.parent = (void *)pth; QUEUE_PUSH(pth->message_queue, MESSAGE, &msg); DEBUG_LOGGER(pth->logger, "Added message transaction[%d] to %s:%d via %d total %d", tid, conn->ip, conn->port, conn->fd, QTOTAL(pth->message_queue)); ret = 0; } return ret; }
/* push message to message queue */ int conn_push_message(CONN *conn, int message_id) { MESSAGE msg = {0}; int ret = -1; if(conn && (message_id & MESSAGE_ALL) ) { msg.msg_id = message_id; msg.fd = conn->fd; msg.handler = conn; msg.parent = conn->parent; QUEUE_PUSH(conn->message_queue, MESSAGE, &msg); DEBUG_LOGGER(conn->logger, "Pushed message[%s] to message_queue[%08x] " "on %s:%d via %d total %d handler[%08x] parent[%08x]", MESSAGE_DESC(message_id), conn->message_queue, conn->ip, conn->port, conn->fd, QTOTAL(conn->message_queue), conn, conn->parent); ret = 0; } return ret; }
/* pop task */ int qindex_pop_task(QINDEX *qindex, QTASK *task) { int taskid = -1, nodeid = -1, id = -1; QTASK *tasks = NULL; if(qindex && task && QTOTAL(qindex->queue) > 0) { MUTEX_LOCK(qindex->mutex); iqueue_pop(qindex->queue, &taskid); if(taskid >= 0 && taskid < (Q_TASKS_MAX * Q_NODE_MAX) && (nodeid = taskid/Q_TASKS_MAX) < Q_NODE_MAX && (tasks = qindex->state->nodes[nodeid].tasks) && (id = (taskid % Q_TASKS_MAX)) >= 0) { memcpy(task, &(tasks[id]), sizeof(QTASK)); } else taskid = -1; MUTEX_UNLOCK(qindex->mutex); } return taskid; }