/* * Clear data associated with connections, so that * if all msgs have been msgcleared, the connection * can be freed. Note that this does *not* free the tpkt * and rpkt; they are freed in msgput with the msg itself. * The io write thread might still be holding a ref to msg * even once the connection has finished with it. */ void msgclear(Msg *m) { if(m->c){ m->c->nmsg--; m->c = nil; } if(m->oldm){ msgput(m->oldm); m->oldm = nil; } if(m->fid){ fidput(m->fid); m->fid = nil; } if(m->afid){ fidput(m->afid); m->afid = nil; } if(m->newfid){ fidput(m->newfid); m->newfid = nil; } if(m->rx.type == Ropenfd && m->rx.unixfd >= 0){ close(m->rx.unixfd); m->rx.unixfd = -1; } }
void inputthread(void *arg) { uchar *pkt; int n, nn, tag; Msg *m; Ioproc *io; threadsetname("input"); if(verbose) fprint(2, "%T input thread\n"); io = ioproc(); USED(arg); while((pkt = read9ppkt(io, 0)) != nil){ n = GBIT32(pkt); if(n < 7){ fprint(2, "%T short 9P packet from server\n"); free(pkt); continue; } if(verbose > 2) fprint(2, "%T read %.*H\n", n, pkt); tag = GBIT16(pkt+5); if((m = msgget(tag)) == nil){ fprint(2, "%T unexpected 9P response tag %d\n", tag); free(pkt); continue; } if((nn = convM2S(pkt, n, &m->rx)) != n){ fprint(2, "%T bad packet - convM2S %d but %d\n", nn, n); free(pkt); msgput(m); continue; } if(verbose > 1) fprint(2, "%T * -> %F%s\n", &m->rx, m->internal ? " (internal)" : ""); m->rpkt = pkt; m->rx.tag = m->ctag; if(m->internal) sendp(m->c->internal, m); else if(m->c->outq) sendq(m->c->outq, m); else msgput(m); } closeioproc(io); /*fprint(2, "%T input eof\n"); */ threadexitsall(0); }
static void test_anon(abts_case *tc, void *data) { apr_proc_t proc; apr_status_t rv; apr_shm_t *shm; apr_size_t retsize; int cnt, i; int recvd; rv = apr_shm_create(&shm, SHARED_SIZE, NULL, p); APR_ASSERT_SUCCESS(tc, "Error allocating shared memory block", rv); ABTS_PTR_NOTNULL(tc, shm); retsize = apr_shm_size_get(shm); ABTS_INT_EQUAL(tc, SHARED_SIZE, retsize); boxes = apr_shm_baseaddr_get(shm); ABTS_PTR_NOTNULL(tc, boxes); rv = apr_proc_fork(&proc, p); if (rv == APR_INCHILD) { /* child */ int num = msgwait(5, 0, N_BOXES); /* exit with the number of messages received so that the parent * can check that all messages were received. */ exit(num); } else if (rv == APR_INPARENT) { /* parent */ i = N_BOXES; cnt = 0; while (cnt++ < N_MESSAGES) { if ((i-=3) < 0) { i += N_BOXES; /* start over at the top */ } msgput(i, MSG); apr_sleep(apr_time_make(0, 10000)); } } else { ABTS_FAIL(tc, "apr_proc_fork failed"); } /* wait for the child */ rv = apr_proc_wait(&proc, &recvd, NULL, APR_WAIT); ABTS_INT_EQUAL(tc, N_MESSAGES, recvd); rv = apr_shm_destroy(shm); APR_ASSERT_SUCCESS(tc, "Error destroying shared memory block", rv); }
void outputthread(void *arg) { Msg *m; Ioproc *io; USED(arg); io = ioproc(); threadsetname("output"); while((m = recvq(outq)) != nil){ if(m->sync){ sendp(m->c->outqdead, nil); continue; } if(verbose > 1) fprint(2, "%T * <- %F\n", &m->tx); rewritehdr(&m->tx, m->tpkt); if(mwrite9p(io, 1, m->tpkt) < 0) sysfatal("output error: %r"); msgput(m); } closeioproc(io); fprint(2, "%T output eof\n"); threadexitsall(0); }
void connoutthread(void *arg) { int err; Conn *c; Msg *m, *om; Ioproc *io; c = arg; io = ioproc(); threadsetname("connout %s", c->dir); while((m = recvq(c->outq)) != nil){ err = m->tx.type+1 != m->rx.type; if(!err && m->isopenfd) if(xopenfd(m) < 0) continue; switch(m->tx.type){ case Tflush: om = m->oldm; if(om) if(delhash(om->c->tag, om->ctag, om) == 0) msgput(om); break; case Tclunk: case Tremove: if(m->fid) if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0) fidput(m->fid); break; case Tauth: if(err && m->afid){ if(verbose) fprint(2, "%T auth error\n"); if(delhash(m->c->fid, m->afid->cfid, m->afid) == 0) fidput(m->afid); } break; case Tattach: if(err && m->fid) if(delhash(m->c->fid, m->fid->cfid, m->fid) == 0) fidput(m->fid); break; case Twalk: if(err || m->rx.nwqid < m->tx.nwname) if(m->tx.fid != m->tx.newfid && m->newfid) if(delhash(m->c->fid, m->newfid->cfid, m->newfid) == 0) fidput(m->newfid); break; case Tread: break; case Tstat: break; case Topen: case Tcreate: m->fid->isdir = (m->rx.qid.type & QTDIR); break; } if(delhash(m->c->tag, m->ctag, m) == 0) msgput(m); if(verbose > 1) fprint(2, "%T fd#%d <- %F\n", c->fd, &m->rx); rewritehdr(&m->rx, m->rpkt); if(mwrite9p(io, c->fd, m->rpkt) < 0) if(verbose) fprint(2, "%T write error: %r\n"); msgput(m); if(c->inputstalled && c->nmsg < MAXMSG) nbsendp(c->inc, 0); } closeioproc(io); free(c->outq); c->outq = nil; sendp(c->outqdead, nil); }
static void openfdthread(void *v) { Conn *c; Fid *fid; Msg *m; int n; vlong tot; Ioproc *io; char buf[1024]; c = v; fid = c->fdfid; io = ioproc(); threadsetname("openfd %s", c->fdfid); tot = 0; m = nil; if(c->fdmode == OREAD){ for(;;){ if(verbose) fprint(2, "%T tread..."); m = msgnew(0); m->internal = 1; m->c = c; m->tx.type = Tread; m->tx.count = msize - IOHDRSZ; m->tx.fid = fid->fid; m->tx.tag = m->tag; m->tx.offset = tot; m->fid = fid; fid->ref++; msgincref(m); sendomsg(m); recvp(c->internal); if(m->rx.type == Rerror){ /* fprint(2, "%T read error: %s\n", m->rx.ename); */ break; } if(m->rx.count == 0) break; tot += m->rx.count; if(iowrite(io, c->fd, m->rx.data, m->rx.count) != m->rx.count){ /* fprint(2, "%T pipe write error: %r\n"); */ break; } msgput(m); msgput(m); m = nil; } }else{ for(;;){ if(verbose) fprint(2, "%T twrite..."); n = sizeof buf; if(n > msize) n = msize; if((n=ioread(io, c->fd, buf, n)) <= 0){ if(n < 0) fprint(2, "%T pipe read error: %r\n"); break; } m = msgnew(0); m->internal = 1; m->c = c; m->tx.type = Twrite; m->tx.fid = fid->fid; m->tx.data = buf; m->tx.count = n; m->tx.tag = m->tag; m->tx.offset = tot; m->fid = fid; fid->ref++; msgincref(m); sendomsg(m); recvp(c->internal); if(m->rx.type == Rerror){ /* fprint(2, "%T write error: %s\n", m->rx.ename); */ } tot += n; msgput(m); msgput(m); m = nil; } } if(verbose) fprint(2, "%T eof on %d fid %d\n", c->fd, fid->fid); close(c->fd); closeioproc(io); if(m){ msgput(m); msgput(m); } if(verbose) fprint(2, "%T eof on %d fid %d ref %d\n", c->fd, fid->fid, fid->ref); if(--fid->openfd == 0){ m = msgnew(0); m->internal = 1; m->c = c; m->tx.type = Tclunk; m->tx.tag = m->tag; m->tx.fid = fid->fid; m->fid = fid; fid->ref++; msgincref(m); sendomsg(m); recvp(c->internal); msgput(m); msgput(m); } fidput(fid); c->fdfid = nil; chanfree(c->internal); c->internal = 0; free(c); }
void connthread(void *arg) { int i, fd; Conn *c; Hash *h, *hnext; Msg *m, *om, *mm, sync; Fid *f; Ioproc *io; c = arg; threadsetname("conn %s", c->dir); io = ioproc(); fd = ioaccept(io, c->fd, c->dir); if(fd < 0){ if(verbose) fprint(2, "%T accept %s: %r\n", c->dir); goto out; } close(c->fd); c->fd = fd; threadcreate(connoutthread, c, STACK); while((m = mread9p(io, c->fd)) != nil){ if(verbose > 1) fprint(2, "%T fd#%d -> %F\n", c->fd, &m->tx); m->c = c; m->ctag = m->tx.tag; c->nmsg++; if(verbose > 1) fprint(2, "%T fd#%d: new msg %p\n", c->fd, m); if(puthash(c->tag, m->tx.tag, m) < 0){ err(m, "duplicate tag"); continue; } msgincref(m); switch(m->tx.type){ case Tversion: m->rx.tag = m->tx.tag; m->rx.msize = m->tx.msize; if(m->rx.msize > msize) m->rx.msize = msize; m->rx.version = "9P2000"; m->rx.type = Rversion; send9pmsg(m); continue; case Tflush: if((m->oldm = gethash(c->tag, m->tx.oldtag)) == nil){ m->rx.tag = m->tx.tag; m->rx.type = Rflush; send9pmsg(m); continue; } msgincref(m->oldm); break; case Tattach: m->afid = nil; if(m->tx.afid != NOFID && (m->afid = gethash(c->fid, m->tx.afid)) == nil){ err(m, "unknown fid"); continue; } if(m->afid) m->afid->ref++; m->fid = fidnew(m->tx.fid); if(puthash(c->fid, m->tx.fid, m->fid) < 0){ err(m, "duplicate fid"); continue; } m->fid->ref++; if(attached && m->afid==nil){ if(m->tx.aname[0] && strcmp(xaname, m->tx.aname) != 0){ err(m, "invalid attach name"); continue; } m->tx.afid = xafid; m->tx.aname = xaname; m->tx.uname = getuser(); /* what srv.c used */ repack(&m->tx, &m->tpkt); } break; case Twalk: if((m->fid = gethash(c->fid, m->tx.fid)) == nil){ err(m, "unknown fid"); continue; } m->fid->ref++; if(m->tx.newfid == m->tx.fid){ m->fid->ref++; m->newfid = m->fid; }else{ m->newfid = fidnew(m->tx.newfid); if(puthash(c->fid, m->tx.newfid, m->newfid) < 0){ err(m, "duplicate fid"); continue; } m->newfid->ref++; } break; case Tauth: if(attached){ err(m, "authentication not required"); continue; } if(noauth){ err(m, "authentication rejected"); continue; } m->afid = fidnew(m->tx.afid); if(puthash(c->fid, m->tx.afid, m->afid) < 0){ err(m, "duplicate fid"); continue; } m->afid->ref++; break; case Tcreate: if(m->tx.perm&(DMSYMLINK|DMDEVICE|DMNAMEDPIPE|DMSOCKET)){ err(m, "unsupported file type"); continue; } goto caseTopen; case Topenfd: if(m->tx.mode&~(OTRUNC|3)){ err(m, "bad openfd mode"); continue; } m->isopenfd = 1; m->tx.type = Topen; m->tpkt[4] = Topen; /* fall through */ caseTopen: case Topen: case Tclunk: case Tread: case Twrite: case Tremove: case Tstat: case Twstat: if((m->fid = gethash(c->fid, m->tx.fid)) == nil){ err(m, "unknown fid"); continue; } m->fid->ref++; break; } /* have everything - translate and send */ m->c = c; m->ctag = m->tx.tag; m->tx.tag = m->tag; if(m->fid) m->tx.fid = m->fid->fid; if(m->newfid) m->tx.newfid = m->newfid->fid; if(m->afid) m->tx.afid = m->afid->fid; if(m->oldm) m->tx.oldtag = m->oldm->tag; /* reference passes to outq */ sendq(outq, m); while(c->nmsg >= MAXMSG){ c->inputstalled = 1; recvp(c->inc); } } if(verbose) fprint(2, "%T fd#%d eof; flushing conn\n", c->fd); /* flush all outstanding messages */ for(i=0; i<NHASH; i++){ while((h = c->tag[i]) != nil){ om = h->v; msgincref(om); /* for us */ m = msgnew(0); m->internal = 1; m->c = c; c->nmsg++; m->tx.type = Tflush; m->tx.tag = m->tag; m->tx.oldtag = om->tag; m->oldm = om; msgincref(om); msgincref(m); /* for outq */ sendomsg(m); mm = recvp(c->internal); assert(mm == m); msgput(m); /* got from recvp */ msgput(m); /* got from msgnew */ if(delhash(c->tag, om->ctag, om) == 0) msgput(om); /* got from hash table */ msgput(om); /* got from msgincref */ } } /* * outputthread has written all its messages * to the remote connection (because we've gotten all the replies!), * but it might not have gotten a chance to msgput * the very last one. sync up to make sure. */ memset(&sync, 0, sizeof sync); sync.sync = 1; sync.c = c; sendq(outq, &sync); recvp(c->outqdead); /* everything is quiet; can close the local output queue. */ sendq(c->outq, nil); recvp(c->outqdead); /* should be no messages left anywhere. */ assert(c->nmsg == 0); /* clunk all outstanding fids */ for(i=0; i<NHASH; i++){ for(h=c->fid[i]; h; h=hnext){ f = h->v; m = msgnew(0); m->internal = 1; m->c = c; c->nmsg++; m->tx.type = Tclunk; m->tx.tag = m->tag; m->tx.fid = f->fid; m->fid = f; f->ref++; msgincref(m); sendomsg(m); mm = recvp(c->internal); assert(mm == m); msgclear(m); msgput(m); /* got from recvp */ msgput(m); /* got from msgnew */ fidput(f); /* got from hash table */ hnext = h->next; free(h); } } out: closeioproc(io); assert(c->nmsg == 0); assert(c->nfid == 0); close(c->fd); chanfree(c->internal); c->internal = 0; chanfree(c->inc); c->inc = 0; free(c->inq); c->inq = 0; free(c); }
char * read_sol_ASL(ASL *asl, real **xp, real **yp) { int binary, flag1, i, j, je, n, need_vbtol; FILE *f; char buf[512], *s, *se; real vbtol, *y; ftnlen L, L1, L2; fint Objno[2], Options[14], nOpts, *z; msginfo mi; if (!asl || asl->i.ASLtype < 1 || asl->i.ASLtype > 5) badasl_ASL(asl,0,"read_soln"); strcpy(stub_end, ".sol"); f = fopen(filename, "rb"); if (!f) { fprintf(Stderr, "Can't open %s\n", filename); fflush(Stderr); return 0; } if (fread(&L, sizeof(ftnlen), 1, f) && L == 6) { /* binary files may be written by Fortran unformatted writes */ binary = 1; if (!fread(buf, 6, 1, f) || strncmp(buf,"binary",6) || !fread(&L, sizeof(ftnlen), 1, f) || L != 6) { badbinary: fprintf(Stderr, "bad binary file %s\n", filename); fflush(Stderr); goto done; } } else { binary = 0; rewind(f); } L1 = 0; z = 0; /* Read termination msg */ nOpts = i = need_vbtol = 0; mi.msg = mi.msg0 = (char *)Malloc(mi.msglen = MSGGULP); mi.msgend = mi.msg0 + MSGGULP; if (binary) { for(;; i++) { if (!fread(&L,sizeof(ftnlen),1,f)) goto early_eof; if ((L1 = L)) { do { n = L < sizeof(buf) ? (int)L : (int)sizeof(buf); L -= n; if (!fread(buf, n, 1, f)) goto early_eof; if (!L) { while(--n >= 0 && buf[n] == ' '); n++; } msgput(&mi, buf, n); } while(L); msgput(&mi, "\n", 1); } if (!fread(&L, sizeof(ftnlen), 1, f)) goto early_eof; if (L != L1) goto badbinary; if (!L) break; } L1 = n_con * sizeof(real); if (!fread(&L, sizeof(ftnlen), 1, f)) goto badbinary; if (L >= 3*sizeof(fint) + 7) { /* check for Options */ if (!fread(buf, 7, 1, f)) goto badbinary; if (strncmp(buf, "Options", 7)) goto badbinary; if (!fread(&Options, sizeof(fint), 3, f)) goto badbinary; nOpts = Options[0]; if (nOpts < 3 || nOpts > 9) { bad_nOpts: fprintf(Stderr, "expected nOpts between 3 and 9; got %ld: ", (long)nOpts); goto badbinary; } if (Options[2] == 3) { nOpts -= 2; need_vbtol = 1; } L2 = (nOpts + 5)*sizeof(fint) + 7; if (need_vbtol) L2 += sizeof(real); if (L != L2) goto badbinary; if (!fread(Options+3, sizeof(fint), nOpts + 2, f)) goto badbinary; if (need_vbtol && !fread(&vbtol, sizeof(real), 1, f)) goto badbinary; if (!fread(&L2, sizeof(ftnlen), 1, f) || L != L2) goto badbinary; } else if (L != L1) goto badbinary; } else { for(;; i++) { if (!fgets(buf, sizeof(buf), f)) { early_eof: fprintf(Stderr, "early end of file reading %s\n", filename); fflush(Stderr); done: fclose(f); return 0; } if (*buf == '\n' || (*buf == '\r' && buf[1] == '\n')) break; msgput(&mi, buf, strlen(buf)); } while((j = getc(f)) == '\n'); if (j != 'O') ungetc(j,f); else { if (!fgets(buf, sizeof(buf), f)) goto early_eof; if (!strncmp(buf, "ptions", 6)) { for(j = 0; j <3; j++) { if (!fgets(buf, sizeof(buf), f)) goto early_eof; Options[j] = strtol(buf,&se,10); if (se == buf) goto badline; } nOpts = Options[0]; if (nOpts < 3 || nOpts > 9) goto bad_nOpts; if (Options[2] == 3) { nOpts -= 2; need_vbtol = 1; } je = (int)nOpts + 4; for(j = 3; j <= je; j++) { if (!fgets(buf, sizeof(buf), f)) goto early_eof; Options[j] = strtol(buf,&se,10); if (se == buf) goto badline; } if (need_vbtol && !fgets(buf, sizeof(buf), f)) goto early_eof; /* We don't do anything here with vbtol, */ /* so we don't bother converting it. */ } } } memcpy(ampl_options, Options, (nOpts+1)*sizeof(fint)); msgput(&mi, "", 1); /* add null to end */ if (i) fflush(stdout); if (nOpts) { z = Options + nOpts + 1; j = (int)z[3]; if (j > n_var || j < 0) { badnumber(asl, j, n_var, "variables"); goto done; } j = (int)z[1]; if (j > n_con || j < 0) { badnumber(asl, j, n_con, "constraints"); goto done; } if (binary) { L1 = j * sizeof(real); if (!fread(&L, sizeof(ftnlen), 1, f)) goto badbinary; if (L != L1) goto badbinary; } } else j = n_con; if (!j) { *yp = 0; goto get_x; } y = *yp = (real *)Malloc(n_con * sizeof(real)); if (binary) { if (fread(y, sizeof(real), j, f) != j) goto early_eof; if (!fread(&L, sizeof(ftnlen), 1, f) || L != L1) goto badbinary; y += j; } else for(i = 0; i < j; i++) { if (!fgets(buf, sizeof(buf), f)) goto early_eof; if (!decstring(buf, y++)) continue; badline: fprintf(Stderr, "bad line in %s: %s", filename, buf); fflush(Stderr); goto done; } y = *yp; while(j < n_con) y[j++] = 0; get_x: Objno[0] = 0; Objno[1] = -1; flag1 = asl->i.flags & ~1;; if (!(j = nOpts ? (int)z[3] : n_var)) { *xp = 0; goto ret; } y = *xp = (real *)Malloc(n_var*sizeof(real)); if (binary) { L1 = j * sizeof(real); if (!fread(&L, sizeof(ftnlen), 1, f) || L != L1) goto badbinary; if (fread(y, sizeof(real), j, f) != j) goto early_eof; y += j; /* do we have an obj_no ? */ if (!fread(&L, sizeof(ftnlen), 1, f) || L != L1) goto badbinary; if (fread(&L, sizeof(ftnlen), 1, f)) { i = 1; if (L == 2*sizeof(fint)) { i = 2; flag1 |= 1; } else if (L != sizeof(fint)) goto badbinary; if (!fread(Objno, i*sizeof(fint), 1, f)) goto badbinary; } } else { for(i = j; i > 0; i--) { if (!fgets(buf, sizeof(buf), f)) goto early_eof; if (decstring(buf, y++)) goto badline; } if (fgets(buf,sizeof(buf), f)) { if (strncmp(buf,"objno ",6)) { extra_line: fprintf(Stderr, "Bug: extra line in %s:\n%s", filename, buf); fflush(Stderr); } else { Objno[0] = strtol(buf+6, &se, 10); if (se == buf+6 || *se > ' ') goto extra_line; if (*se == ' ') { Objno[1] = strtol(se,&s,10); if (s == se || *s > ' ') goto extra_line; flag1 |= 1; } } } } asl->i.flags = flag1; obj_no = (int)Objno[0]; solve_result_num = (int)Objno[1]; y = *xp; while(j < n_var) y[j++] = 0; ret: fclose(f); return (char*)Realloc(mi.msg0, mi.msglen); }
static apr_status_t test_anon(apr_pool_t *parpool) { apr_status_t rv; apr_pool_t *pool; apr_shm_t *shm; apr_size_t retsize; pid_t pid; int cnt, i, exit_int; rv = apr_pool_create(&pool, parpool); if (rv != APR_SUCCESS) { fprintf(stderr, "Error creating child pool\n"); return rv; } printf("Creating anonymous shared memory block (%" APR_SIZE_T_FMT " bytes)........", SHARED_SIZE); rv = apr_shm_create(&shm, SHARED_SIZE, NULL, pool); if (rv != APR_SUCCESS) { fprintf(stderr, "Error allocating shared memory block\n"); return rv; } fprintf(stdout, "OK\n"); printf("Checking size...%" APR_SIZE_T_FMT " bytes...", retsize = apr_shm_size_get(shm)); if (retsize != SHARED_SIZE) { fprintf(stderr, "Error allocating shared memory block\n"); return rv; } fprintf(stdout, "OK\n"); printf("Allocating shared mbox memory for %d boxes ..............", N_BOXES); boxes = apr_shm_baseaddr_get(shm); if (boxes == NULL) { fprintf(stderr, "Error creating message boxes.\n"); return rv; } fprintf(stdout, "OK\n"); printf("Shared Process Test (child/parent)\n"); pid = fork(); if (pid == 0) { /* child */ msgwait(5, 0, N_BOXES); exit(0); } else if (pid > 0) { /* parent */ i = N_BOXES; cnt = N_MESSAGES; while (--cnt > 0) { if ((i-=3) < 0) { i += N_BOXES; /* start over at the top */ } msgput(i, "Sending a message\n"); apr_sleep(apr_time_make(0, 10000)); } } else { printf("Error creating a child process\n"); return errno; } /* wait for the child */ printf("Waiting for child to exit.\n"); if (waitpid(pid, &exit_int, 0) < 0) { return errno; } printf("Destroying shared memory segment..."); rv = apr_shm_destroy(shm); if (rv != APR_SUCCESS) { printf("FAILED\n"); return rv; } printf("OK\n"); apr_pool_destroy(pool); return APR_SUCCESS; }