void np_conn_respond(Npreq *req) { int n; Npconn *conn; Nptrans *trans; Npfcall *rc; trans = NULL; conn = req->conn; rc = req->rcall; pthread_mutex_lock(&conn->lock); if (conn->trans && !conn->resetting && rc) { if (conn->srv->debuglevel) { print_timestamp(stderr); fprintf(stderr, " >>> (%p) ", conn); np_printfcall(stderr, rc, conn->dotu); if ( req->tcall->encryptor ) fprintf(stderr, " (encrypted)"); fprintf(stderr, "\n"); } if ( req->tcall->encryptor ) { /* Request was encrypted => encrypt also the response */ rc->encryptor = req->tcall->encryptor; rc = np_encrypt_fcall(rc); req->rcall = rc; } n = np_trans_write(conn->trans, rc->pkt, rc->size); if (n <= 0) { trans = conn->trans; conn->trans = NULL; } } np_conn_free_incall(req->conn, req->tcall); free(req->rcall); req->tcall = NULL; req->rcall = NULL; pthread_mutex_unlock(&conn->lock); if (conn->resetting) { pthread_mutex_lock(&conn->srv->lock); pthread_cond_broadcast(&conn->resetcond); pthread_mutex_unlock(&conn->srv->lock); } if (trans) np_trans_destroy(trans); /* np_conn_read_proc will take care of resetting */ }
void np_conn_respond(Npreq *req) { int n, send; Npconn *conn; Nptrans *trans; Npfcall *rc; trans = NULL; conn = req->conn; rc = req->rcall; if (!rc) goto done; pthread_mutex_lock(&conn->lock); send = conn->trans && !conn->resetting; pthread_mutex_unlock(&conn->lock); if (send) { pthread_mutex_lock(&conn->wlock); if (conn->srv->debuglevel) { fprintf(stderr, ">>> (%p) ", conn); np_printfcall(stderr, rc, conn->dotu); fprintf(stderr, "\n"); } n = np_trans_write(conn->trans, rc->pkt, rc->size); pthread_mutex_unlock(&conn->wlock); if (n <= 0) { pthread_mutex_lock(&conn->lock); trans = conn->trans; conn->trans = NULL; pthread_mutex_unlock(&conn->lock); } } done: np_conn_free_incall(req->conn, req->tcall, 1); free(req->rcall); req->tcall = NULL; req->rcall = NULL; if (conn->resetting) { pthread_mutex_lock(&conn->srv->lock); pthread_cond_broadcast(&conn->resetcond); pthread_mutex_unlock(&conn->srv->lock); } if (trans) np_trans_destroy(trans); /* np_conn_read_proc will take care of resetting */ }
static void * np_conn_read_proc(void *a) { int i, n, size, msize; Npsrv *srv; Npconn *conn; Nptrans *trans; Npreq *req; Npfcall *fc, *fc1; pthread_detach(pthread_self()); conn = a; np_conn_incref(conn); srv = conn->srv; msize = conn->msize; fc = np_conn_new_incall(conn); n = 0; while (conn->trans && (i = np_trans_read(conn->trans, fc->pkt + n, msize - n)) > 0) { pthread_mutex_lock(&conn->lock); if (conn->resetting) { while(conn->resetting) pthread_cond_wait(&conn->resetdonecond, &conn->lock); n = 0; /* discard all input */ i = 0; } pthread_mutex_unlock(&conn->lock); n += i; again: if (n < 4) continue; size = fc->pkt[0] | (fc->pkt[1]<<8) | (fc->pkt[2]<<16) | (fc->pkt[3]<<24); if (n < size) continue; if (!np_deserialize(fc, fc->pkt, conn->dotu)) break; if (conn->srv->debuglevel) { fprintf(stderr, "<<< (%p) ", conn); np_printfcall(stderr, fc, conn->dotu); fprintf(stderr, "\n"); } fc1 = np_conn_new_incall(conn); if (n > size) memmove(fc1->pkt, fc->pkt + size, n - size); n -= size; req = np_req_alloc(conn, fc); pthread_mutex_lock(&srv->lock); if (!conn->resetting) np_srv_add_req(srv, req); else np_req_unref(req); pthread_mutex_unlock(&srv->lock); fc = fc1; if (n > 0) goto again; } pthread_mutex_lock(&conn->lock); trans = conn->trans; conn->trans = NULL; np_conn_free_incall(conn, fc); pthread_mutex_unlock(&conn->lock); np_srv_remove_conn(conn->srv, conn); np_conn_reset(conn, 0, 0); if (trans) np_trans_destroy(trans); np_conn_decref(conn); return NULL; }