plan9port

fork of plan9port with libvec, libstr and libsdb
Log | Files | Refs | README | LICENSE

commit 43db87f1fcb51065ef50beae9da8b6310ccf1cae
parent 4bef0baf95850b1ee0fa5f5a8fda20872ce59426
Author: rsc <devnull@localhost>
Date:   Mon, 27 Dec 2004 00:13:33 +0000

bug fix -- need to enqueue before sending the packet,
in case the response comes back and another thread
tries to give it to us, all before we are enqueued.

Diffstat:
Msrc/libmux/mux.c | 18+++++++++++++-----
1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/src/libmux/mux.c b/src/libmux/mux.c @@ -39,10 +39,14 @@ muxrpc(Mux *mux, void *tx) return nil; r->r.l = &mux->lk; - /* assign the tag */ + /* assign the tag, add selves to response queue */ qlock(&mux->lk); tag = gettag(mux, r); +//print("gettag %p %d\n", r, tag); + enqueue(mux, r); qunlock(&mux->lk); + + /* actually send the packet */ if(tag < 0 || mux->settag(mux, tx, tag) < 0 || _muxsend(mux, tx) < 0){ qlock(&mux->lk); puttag(mux, r); @@ -50,10 +54,7 @@ muxrpc(Mux *mux, void *tx) return nil; } - /* add ourselves to sleep queue */ qlock(&mux->lk); - enqueue(mux, r); - /* wait for our packet */ while(mux->muxer && !r->p){ rsleep(&r->r); @@ -71,6 +72,7 @@ muxrpc(Mux *mux, void *tx) tag = mux->gettag(mux, p); else tag = ~0; +//print("mux tag %d\n", tag); qlock(&mux->lk); if(p == nil){ /* eof -- just give up and pass the buck */ dequeue(mux, r); @@ -83,8 +85,14 @@ muxrpc(Mux *mux, void *tx) continue; } r2 = mux->wait[tag]; + if(r2 == nil){ + fprint(2, "%s: bad rpc tag %ux (no one waiting on that tag)\n", argv0, tag); + /* must leak packet! don't know how to free it! */ + continue; + } r2->p = p; dequeue(mux, r2); + puttag(mux, r2); rwakeup(&r2->r); } mux->muxer = 0; @@ -93,8 +101,8 @@ muxrpc(Mux *mux, void *tx) if(mux->sleep.next != &mux->sleep) rwakeup(&mux->sleep.next->r); } +//print("finished %p\n", r); p = r->p; - puttag(mux, r); qunlock(&mux->lk); return p; }