tbug 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. - plan9port - [fork] Plan 9 from user space
 (HTM) git clone git://src.adamsgaard.dk/plan9port
 (DIR) Log
 (DIR) Files
 (DIR) Refs
 (DIR) README
 (DIR) LICENSE
       ---
 (DIR) commit 43db87f1fcb51065ef50beae9da8b6310ccf1cae
 (DIR) parent 4bef0baf95850b1ee0fa5f5a8fda20872ce59426
 (HTM) 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
       ttries to give it to us, all before we are enqueued.
       
       Diffstat:
         M src/libmux/mux.c                    |      18 +++++++++++++-----
       
       1 file changed, 13 insertions(+), 5 deletions(-)
       ---
 (DIR) diff --git a/src/libmux/mux.c b/src/libmux/mux.c
       t@@ -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);
       t@@ -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);
       t@@ -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);
       t@@ -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;
       t@@ -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;
        }