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 */ }
/* Called by srv workers to transmit req->rcall->pkt. */ void np_conn_respond(Npreq *req) { int n, send; Npconn *conn = req->conn; Npsrv *srv = conn->srv; Npfcall *rc = req->rcall; Nptrans *trans = NULL; if (!rc) goto done; xpthread_mutex_lock(&conn->lock); send = conn->trans && !conn->resetting; xpthread_mutex_unlock(&conn->lock); if (send) { if ((srv->flags & SRV_FLAGS_DEBUG_9PTRACE)) _debug_trace (srv, rc); xpthread_mutex_lock(&conn->wlock); n = np_trans_write(conn->trans, rc->pkt, rc->size); conn->reqs_out++; xpthread_mutex_unlock(&conn->wlock); if (n <= 0) { /* write error */ xpthread_mutex_lock(&conn->lock); trans = conn->trans; conn->trans = NULL; xpthread_mutex_unlock(&conn->lock); } } done: _free_npfcall(req->tcall); free(req->rcall); req->tcall = NULL; req->rcall = NULL; if (conn->resetting) { xpthread_mutex_lock(&conn->srv->lock); xpthread_cond_broadcast(&conn->resetcond); xpthread_mutex_unlock(&conn->srv->lock); } if (trans) /* np_conn_read_proc will take care of resetting */ np_trans_destroy(trans); }
static void _flush_series (Npcfsys *fs, Npcfid *root) { Npfcall *rc = NULL, *tc = NULL, *ac = NULL; u16 tag, flushtag; int n, i; struct sigaction sa; assert (fs->trans != NULL); sa.sa_flags = 0; sigemptyset(&sa.sa_mask); sa.sa_handler = _alarm_clock; if (sigaction (SIGALRM, &sa, NULL) < 0) err_exit ("sigaction"); /* write 100 tversions */ for (i = 0; i < 100; i++) { if (!(tc = np_create_tversion (fs->msize, "9P2000.L"))) msg_exit ("out of memory"); flushtag = tag = npc_get_id(fs->tagpool); np_set_tag(tc, tag); n = np_trans_write(fs->trans, tc->pkt, tc->size); if (n < 0) errn_exit (np_rerror (), "np_trans_write"); if (n != tc->size) msg_exit ("np_trans_write came up unexpectedly short"); //msg ("sent tversion tag %d", tc->tag); free(tc); } msg ("sent 100 tversions"); /* flush the most recent */ if (!(ac = np_create_tflush (flushtag))) msg_exit ("out of memory"); tag = npc_get_id(fs->tagpool); np_set_tag(ac, tag); n = np_trans_write(fs->trans, ac->pkt, ac->size); if (n < 0) errn_exit (np_rerror (), "np_trans_write"); if (n != ac->size) msg_exit ("np_trans_write came up unexpectedly short"); //msg ("sent tflush tag %d (flushing tag %d)", ac->tag, flushtag); free (ac); msg ("sent 1 tflush"); /* receive up to 101 responses with 1s timeout */ for (i = 0; i < 101; i++) { if (!(rc = malloc(sizeof(*rc) + fs->msize))) msg_exit ("out of memory"); rc->pkt = (u8*)rc + sizeof(*rc); alarm (1); n = np_trans_read(fs->trans, rc->pkt, fs->msize); if (n < 0) { if (errno == EINTR) break; errn_exit (np_rerror (), "np_trans_read"); } alarm (0); if (n == 0) msg_exit ("np_trans_read: unexpected EOF"); if (!np_deserialize (rc, rc->pkt)) msg_exit ("failed to deserialize response in one go"); //msg ("received tag %d", rc->tag); free(rc); //npc_put_id(fs->tagpool, rc->tag); } if (i == 100 || i == 101) msg ("received 100/101 respones"); else msg ("received %d responses", i); }