int tbx_ns_chksum_write_flush(tbx_ns_t *ns) { char chksum_value[CHKSUM_MAX_SIZE]; int err, n; tbx_tbuf_t buf; log_printf(15, "ns_write_chksum_flush: injecting chksum! ns=%d type=%d bytesleft=" I64T " bsize=" I64T "\n", tbx_ns_getid(ns), tbx_chksum_type(&(ns->write_chksum.chksum)), ns->write_chksum.bytesleft, ns->write_chksum.blocksize); tbx_log_flush(); if (ns_write_chksum_state(ns) == 0) return(0); if (ns->write_chksum.bytesleft == ns->write_chksum.blocksize) return(0); //** Nothing to do n = tbx_chksum_size(&(ns->write_chksum.chksum), CHKSUM_DIGEST_HEX); tbx_chksum_get(&(ns->write_chksum.chksum), CHKSUM_DIGEST_HEX, chksum_value); ns->write_chksum.is_running = 0; //** Don't want to get in an endless loop tbx_tbuf_single(&buf, n, chksum_value); err = _write_netstream_block(ns, apr_time_now() + apr_time_make(5,0), &buf, 0, n, 0); ns->write_chksum.is_running = 1; if (err != 0) { log_printf(10, "ns_write_chksum_flush: ns=%d Error writing chksum! error=%d\n", tbx_ns_getid(ns), err); return(err); } chksum_value[n] = '\0'; log_printf(15, "ns_write_chksum_flush: ns=%d chksum_value=%s\n", tbx_ns_getid(ns), chksum_value); log_printf(15, "ns_write_chksum_flush: end of routine! ns=%d\n err=%d", tbx_ns_getid(ns), err); tbx_log_flush(); return(err); }
int _read_netstream_block(tbx_ns_t *ns, apr_time_t end_time, tbx_tbuf_t *buffer, int pos, int size, int dolock) { int nleft, nbytes, err; tbx_ns_timeout_t dt; tbx_ns_timeout_set(&dt, 1, 0); nleft = size; nbytes = -100; err = NS_OK; while ((nleft > 0) && (err == NS_OK)) { nbytes = _tbx_ns_read(ns, buffer, pos, nleft, dt, dolock); log_printf(15, "read_netstream_block: ns=%d size=%d nleft=%d nbytes=%d pos=%d time=" TT "\n", tbx_ns_getid(ns), size, nleft, nbytes, pos, apr_time_now()); if (apr_time_now() > end_time) { log_printf(15, "read_netstream_block: ns=%d Command timed out! to=" TT " ct=" TT " \n", tbx_ns_getid(ns), end_time, apr_time_now()); err = NS_TIMEOUT; } if (nbytes < 0) { err = nbytes; //** Error with write } else if (nbytes > 0) { //** Normal write pos = pos + nbytes; nleft = nleft - nbytes; err = NS_OK; } } log_printf(15, "read_netstream_block: END ns=%d size=%d nleft=%d nbytes=%d pos=%d\n", tbx_ns_getid(ns), size, nleft, nbytes, pos); return(err); }
void _reap_hportal(host_portal_t *hp, int quick) { host_connection_t *hc; apr_status_t value; int count; tbx_stack_move_to_top(hp->closed_que); while ((hc = (host_connection_t *)tbx_stack_get_current_data(hp->closed_que)) != NULL) { apr_thread_join(&value, hc->recv_thread); log_printf(5, "hp=%s ns=%d\n", hp->skey, tbx_ns_getid(hc->ns)); for (count=0; ((quick == 0) || (count < 2)); count++) { lock_hc(hc); //** Make sure that no one is running close_hc() while we're trying to close it if (hc->closing != 1) { //** Ok to to remove it unlock_hc(hc); tbx_stack_delete_current(hp->closed_que, 0, 0); destroy_host_connection(hc); break; } else { //** Got somone trying ot close it so wait a little bit unlock_hc(hc); apr_sleep(apr_time_from_msec(10)); } } tbx_stack_move_down(hp->closed_que); if (tbx_stack_get_current_data(hp->closed_que) == NULL) tbx_stack_move_to_top(hp->closed_que); //** Restart it needed } }
int tbx_ns_chksum_read_flush(tbx_ns_t *ns) { char ns_value[CHKSUM_MAX_SIZE], chksum_value[CHKSUM_MAX_SIZE]; int err, n; tbx_tbuf_t buf; log_printf(15, "ns_read_chksum_flush: Reading chksum! ns=%d type=%d bleft=" I64T " bsize=" I64T " state=%d\n", tbx_ns_getid(ns), tbx_chksum_type(&(ns->read_chksum.chksum)), ns->read_chksum.bytesleft, ns->read_chksum.blocksize, ns_read_chksum_state(ns)); tbx_log_flush(); if (ns_read_chksum_state(ns) == 0) return(0); if (ns->read_chksum.bytesleft == ns->read_chksum.blocksize) return(0); //** Nothing to do n = tbx_chksum_size(&(ns->read_chksum.chksum), CHKSUM_DIGEST_HEX); ns->read_chksum.is_running = 0; //** Don't want to get in an endless loop tbx_tbuf_single(&buf, n, ns_value); err = _read_netstream_block(ns, apr_time_now() + apr_time_make(5,0), &buf, 0, n, 0); ns_value[n] = '\0'; ns->read_chksum.is_running = 1; log_printf(15, "ns_read_chksum_flush: Finished reading chksum! ns=%d\n", tbx_ns_getid(ns)); tbx_log_flush(); if (err != 0) { log_printf(10, "ns_read_chksum_flush: ns=%d Error reading chksum! error=%d\n", tbx_ns_getid(ns), err); return(err); } tbx_chksum_get(&(ns->read_chksum.chksum), CHKSUM_DIGEST_HEX, chksum_value); log_printf(15, "ns_read_chksum_flush: after tbx_chksum_get! ns=%d\n", tbx_ns_getid(ns)); tbx_log_flush(); err = (strncmp(chksum_value, ns_value, n) == 0) ? 0 : 1; log_printf(15, "ns_read_chksum_flush: ns=%d ns_value=%s cmp=%d\n", tbx_ns_getid(ns), ns_value, err); log_printf(15, "ns_read_chksum_flush: ns=%d chksum_value=%s\n", tbx_ns_getid(ns), chksum_value); if (err != 0) { log_printf(1, "ns_read_chksum_flush: ns=%d chksum error!\n", tbx_ns_getid(ns)); log_printf(1, "ns_read_chksum_flush: ns=%d ns_value=%s cmp=%d\n", tbx_ns_getid(ns), ns_value, err); log_printf(1, "ns_read_chksum_flush: ns=%d chksum_value=%s\n", tbx_ns_getid(ns), chksum_value); } log_printf(15, "ns_read_chksum_flush: end of routine! ns=%d\n err=%d", tbx_ns_getid(ns), err); tbx_log_flush(); return(err); }
int _tbx_ns_read(tbx_ns_t *ns, tbx_tbuf_t *buffer, unsigned int boff, int size, tbx_ns_timeout_t timeout, int dolock) { int total_bytes, i; tbx_tbuf_t ns_tb; if (size == 0) return(0); if (dolock == 1) lock_read_ns(ns); if (ns->sock_status(ns->sock) != 1) { log_printf(15, "read_netstream: Dead connection! ns=%d\n", ns->id); if (dolock == 1) unlock_read_ns(ns); return(-1); } if (ns_read_chksum_state(ns) == 1) { //** We have chksumming enabled if (size > ns->read_chksum.bytesleft) { size = ns->read_chksum.bytesleft; //** Truncate at the block } } //*** 1st grab anything currently in the network buffer *** if (ns->end >= ns->start) { i = ns->end - ns->start + 1; if (i>size) { total_bytes = size; tbx_tbuf_single(&ns_tb, size, &(ns->buffer[ns->start])); tbx_tbuf_copy(&ns_tb, 0, buffer, boff, size, 1); ns->start = ns->start + total_bytes; } else { total_bytes = i; tbx_tbuf_single(&ns_tb, i, &(ns->buffer[ns->start])); tbx_tbuf_copy(&ns_tb, 0, buffer, boff, i, 1); ns->start = 0; ns->end = -1; } } else { //*** Now grab some data off the network port **** total_bytes = ns->read(ns->sock, buffer, boff, size, timeout); } debug_code( if (total_bytes > 0) { // debug_printf(10, "read_netstream: Command : !"); // for (i=0; i< total_bytes; i++) debug_printf(10, "%c", buffer[i]); // debug_printf(10, "! * nbytes =%d\n", total_bytes); flush_debug(); } else if (total_bytes == 0) { debug_printf(10, "read_netstream: No data!\n"); } else { log_printf(10, "read_netstream: Dead connection! ns=%d\n", tbx_ns_getid(ns)); } )
int _tbx_ns_write(tbx_ns_t *ns, tbx_tbuf_t *buffer, unsigned int boff, int bsize, tbx_ns_timeout_t timeout, int dolock) { int total_bytes, i; if (dolock == 1) lock_write_ns(ns); if (ns->sock_status(ns->sock) != 1) { log_printf(15, "write_netstream: connection closed! ns=%d\n", ns->id); if (dolock == 1) unlock_write_ns(ns); return(-1); } if (bsize == 0) { if (dolock == 1) unlock_write_ns(ns); return(0); } if (ns_write_chksum_state(ns) == 1) { //** We have chksumming enabled if (bsize > ns->write_chksum.bytesleft) { bsize = ns->write_chksum.bytesleft; //** Truncate at the block } } total_bytes = ns->write(ns->sock, buffer, boff, bsize, timeout); if (total_bytes == -1) { log_printf(10, "write_netstream: Dead connection! ns=%d\n", tbx_ns_getid(ns)); } ns->last_write = apr_time_now(); if ((ns_write_chksum_state(ns) == 1) && (total_bytes > 0)) { //** We have chksumming enabled tbx_chksum_add(&(ns->write_chksum.chksum), total_bytes, buffer, boff); //** Chksum it ns->write_chksum.bytesleft -= total_bytes; if (ns->write_chksum.bytesleft <= 0) { //** Reached the block size so inject the chksum i = tbx_ns_chksum_write_flush(ns); if (i != 0) total_bytes = NS_CHKSUM; //** Reset the chksum ns->write_chksum.bytesleft = ns->write_chksum.blocksize; tbx_chksum_reset(&(ns->write_chksum.chksum)); } } if (dolock == 1) unlock_write_ns(ns); return(total_bytes); }
void *monitor_thread(apr_thread_t *th, void *data) { tbx_ns_monitor_t *nm = (tbx_ns_monitor_t *)data; tbx_ns_t *ns = nm->ns; int i; log_printf(15, "monitor_thread: Monitoring port %d\n", nm->port); apr_thread_mutex_lock(nm->lock); while (nm->shutdown_request == 0) { apr_thread_mutex_unlock(nm->lock); i = ns->connection_request(ns->sock, 1); if (i == 1) { //** Got a request log_printf(15, "monitor_thread: port=%d ns=%d Got a connection request time=" TT "\n", nm->port, tbx_ns_getid(ns), apr_time_now()); //** Mark that I have a connection pending apr_thread_mutex_lock(nm->lock); nm->is_pending = 1; apr_thread_mutex_unlock(nm->lock); //** Wake up the calling thread apr_thread_mutex_lock(nm->trigger_lock); (*(nm->trigger_count))++; apr_thread_cond_signal(nm->trigger_cond); apr_thread_mutex_unlock(nm->trigger_lock); log_printf(15, "monitor_thread: port=%d ns=%d waiting for accept\n", nm->port, tbx_ns_getid(ns)); //** Sleep until my connection is accepted apr_thread_mutex_lock(nm->lock); while ((nm->is_pending == 1) && (nm->shutdown_request == 0)) { apr_thread_cond_wait(nm->cond, nm->lock); log_printf(15, "monitor_thread: port=%d ns=%d Cond triggered=" TT " trigger_count=%d\n", nm->port, tbx_ns_getid(ns), apr_time_now(), *(nm->trigger_count)); } apr_thread_mutex_unlock(nm->lock); log_printf(15, "monitor_thread: port=%d ns=%d Connection accepted time=" TT "\n", nm->port, tbx_ns_getid(ns), apr_time_now()); //** Update pending count // apr_thread_mutex_lock(nm->trigger_lock); // *(nm->trigger_count)--; // apr_thread_mutex_unlock(nm->trigger_lock); } apr_thread_mutex_lock(nm->lock); } apr_thread_mutex_unlock(nm->lock); //** Lastly shutdown my socket tbx_ns_close(ns); log_printf(15, "monitor_thread: Closing port %d\n", nm->port); apr_thread_exit(th, 0); return(NULL); }
int submit_hp_direct_op(portal_context_t *hpc, op_generic_t *op) { int status; host_portal_t *hp, *shp; host_connection_t *hc; command_op_t *hop = &(op->op->cmd); apr_thread_mutex_lock(hpc->lock); //** Check if we should do a garbage run ** if (hpc->next_check < time(NULL)) { hpc->next_check = time(NULL) + hpc->compact_interval; apr_thread_mutex_unlock(hpc->lock); compact_hportals(hpc); apr_thread_mutex_lock(hpc->lock); } //** Find it in the list or make a new one hp = _lookup_hportal(hpc, hop->hostport); if (hp == NULL) { log_printf(15, "submit_hp_direct_op: New host: %s\n", hop->hostport); hp = create_hportal(hpc, hop->connect_context, hop->hostport, 1, 1, apr_time_from_sec(1)); if (hp == NULL) { log_printf(15, "submit_hp_direct_op: create_hportal failed!\n"); apr_thread_mutex_unlock(hpc->lock); return(-1); } apr_hash_set(hpc->table, hp->skey, APR_HASH_KEY_STRING, (const void *)hp); } apr_thread_mutex_unlock(hpc->lock); log_printf(15, "submit_hp_direct_op: start opid=%d\n", op->base.id); //** Scan the direct list for a free connection hportal_lock(hp); tbx_stack_move_to_top(hp->direct_list); while ((shp = (host_portal_t *)tbx_stack_get_current_data(hp->direct_list)) != NULL) { if (hportal_trylock(shp) == 0) { log_printf(15, "submit_hp_direct_op: opid=%d shp->wl=" I64T " stack_size=%d\n", op->base.id, shp->workload, tbx_stack_count(shp->que)); if (tbx_stack_count(shp->que) == 0) { if (tbx_stack_count(shp->conn_list) > 0) { tbx_stack_move_to_top(shp->conn_list); hc = (host_connection_t *)tbx_stack_get_current_data(shp->conn_list); if (trylock_hc(hc) == 0) { if ((tbx_stack_count(hc->pending_stack) == 0) && (hc->curr_workload == 0)) { log_printf(15, "submit_hp_direct_op(A): before submit ns=%d opid=%d wl=%d\n",tbx_ns_getid(hc->ns), op->base.id, hc->curr_workload); unlock_hc(hc); hportal_unlock(shp); status = submit_hportal(shp, op, 1, 0); log_printf(15, "submit_hp_direct_op(A): after submit ns=%d opid=%d\n",tbx_ns_getid(hc->ns), op->base.id); hportal_unlock(hp); return(status); } unlock_hc(hc); } } else { hportal_unlock(shp); log_printf(15, "submit_hp_direct_op(B): opid=%d\n", op->base.id); status = submit_hportal(shp, op, 1, 0); hportal_unlock(hp); return(status); } } hportal_unlock(shp); } tbx_stack_move_down(hp->direct_list); //** Move to the next hp in the list } //** If I made it here I have to add a new hportal shp = create_hportal(hpc, hop->connect_context, hop->hostport, 1, 1, apr_time_from_sec(1)); if (shp == NULL) { log_printf(15, "submit_hp_direct_op: create_hportal failed!\n"); hportal_unlock(hp); return(-1); } tbx_stack_push(hp->direct_list, (void *)shp); status = submit_hportal(shp, op, 1, 0); hportal_unlock(hp); return(status); }