void np_respond(Npreq *req, Npfcall *rc) { Npsrv *srv; Npreq *freq, *freq1; Npconn *conn; req->rcall = rc; srv = req->conn->srv; pthread_mutex_lock(&srv->lock); if (req->prev) req->prev->next = req->next; else srv->workreqs = req->next; if (req->next) req->next->prev = req->prev; /* remove the flush requests from the working queue */ for(freq = req->flushreq; freq != NULL; freq = freq->flushreq) { if (freq->prev) freq->prev->next = freq->next; else srv->workreqs = freq->next; if (freq->next) freq->next->prev = freq->prev; } pthread_mutex_unlock(&srv->lock); if (req->rcall) { if (req->rcall->id==Rread && req->fid->type&Qtdir) req->fid->diroffset = req->tcall->offset + req->rcall->count; np_set_tag(req->rcall, req->tag); np_conn_send_fcall(req->conn, req->rcall); } freq = req->flushreq; while (freq != NULL) { rc = np_create_rflush(); np_set_tag(rc, freq->tag); conn = freq->conn; np_conn_send_fcall(freq->conn, rc); freq1 = freq->flushreq; np_conn_free_rcall(freq->conn, freq->tcall); reqfree(freq); freq = freq1; } np_conn_free_rcall(req->conn, req->tcall); reqfree(req); }
/* Allocate a new Npfcall to "receive" raw data from fc->pkt. */ static Npfcall * _rcv_buf (Npfcall *fc, int type, const char *fun) { Npfcall *fc2; char s[256]; printf ("%s(%d): %d\n", fun, type, fc->size); np_set_tag (fc, 42); /* see conn.c:np_conn_new_incall () */ if (!(fc2 = malloc (sizeof (*fc2) + TEST_MSIZE))) msg_exit ("out of memory"); fc2->pkt = (u8 *)fc2 + sizeof (*fc2); /* see conn.c::np_conn_read_proc */ memcpy (fc2->pkt, fc->pkt, fc->size); if (!np_deserialize (fc2)) msg_exit ("np_deserialize error in %s", fun); /* check a few things */ if (fc->type != type) msg_exit ("incorrect type in %s", fun); if (fc->size != fc2->size) msg_exit ("size mismatch in %s", fun); if (fc->type != fc2->type) msg_exit ("type mismatch in %s", fun); np_snprintfcall (s, sizeof (s), fc); printf ("%s\n", s); return fc2; }
static void np_respond(Nptpool *tp, Npreq *req, Npfcall *rc) { Npreq *freq; xpthread_mutex_lock(&req->lock); if (req->responded) { free(rc); xpthread_mutex_unlock(&req->lock); np_req_unref(req); return; } req->responded = 1; xpthread_mutex_unlock(&req->lock); xpthread_mutex_lock(&tp->lock); np_srv_remove_workreq(tp, req); for(freq = req->flushreq; freq != NULL; freq = freq->flushreq) np_srv_remove_workreq(tp, freq); xpthread_mutex_unlock(&tp->lock); xpthread_mutex_lock(&req->lock); req->rcall = rc; if (req->rcall) { np_set_tag(req->rcall, req->tag); if (req->fid != NULL) { np_fid_decref(req->fid); req->fid = NULL; } np_conn_respond(req); } for(freq = req->flushreq; freq != NULL; freq = freq->flushreq) { xpthread_mutex_lock(&freq->lock); freq->rcall = np_create_rflush(); np_set_tag(freq->rcall, freq->tag); np_conn_respond(freq); xpthread_mutex_unlock(&freq->lock); np_req_unref(freq); } xpthread_mutex_unlock(&req->lock); np_req_unref(req); }
static int npc_rpc(Npcfsys *fs, Npfcall *tc, Npfcall **rcp) { Npfcall *rc = NULL; u16 tag = P9_NOTAG; int n, ret = -1; if (!fs->trans) { np_uerror(ECONNABORTED); goto done; } if (tc->type != P9_TVERSION) tag = npc_get_id(fs->tagpool); np_set_tag(tc, tag); xpthread_mutex_lock(&fs->lock); n = np_trans_send (fs->trans, tc); if (n >= 0) n = np_trans_recv(fs->trans, &rc, fs->msize); xpthread_mutex_unlock(&fs->lock); if (n < 0) goto done; if (rc == NULL) { np_uerror (EPROTO); /* premature EOF */ goto done; } if (tc->tag != rc->tag) { np_uerror (EPROTO); /* unmatched response */ goto done; } if (rc->type == P9_RLERROR) { np_uerror (rc->u.rlerror.ecode); goto done; } *rcp = rc; ret = 0; done: if (tag != P9_NOTAG) npc_put_id(fs->tagpool, tag); if (ret < 0 && rc != NULL) free (rc); return ret; }
static void np_respond(Nptpool *tp, Npreq *req, Npfcall *rc) { xpthread_mutex_lock(&tp->srv->lock); np_srv_remove_workreq(tp, req); xpthread_mutex_unlock(&tp->srv->lock); xpthread_mutex_lock(&req->lock); req->rcall = rc; if (req->rcall) { np_set_tag(req->rcall, req->tag); if (req->fid != NULL) { np_fid_decref(req->fid); req->fid = NULL; } np_conn_respond(req); } xpthread_mutex_unlock(&req->lock); np_req_unref(req); }
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); }