// -*-c++-*- /* $Id: aios.h,v 1.19 2001/10/29 23:05:50 ericp Exp $ */ /* * * Copyright (C) 1998 David Mazieres (dm@uun.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * USA * */ #ifndef _ASYNC_AIOS_H_ #define _ASYNC_AIOS_H_ 1 #include "str.h" #include "union.h" #include "init.h" #include "cbuf.h" struct timecb_t; INIT(aiosinit); class aios : virtual public refcount { friend class aiosout; typedef callback::ptr rcb_t; typedef callback::ptr wcb_t; int fd; int err; bool eof; bool weof; bool rlock; cbuf inb; bool (aios::*infn) (); rcb_t rcb; strbuf outb; bool wblock; time_t timeoutval; time_t timeoutnext; timecb_t *timeoutcb; str debugname; ssize_t debugiov; vec fdsendq; void fail (int e); void mkrcb (const str &s) { infn = &aios::rnone; rcb_t::ref cb = rcb; rcb = NULL; (*cb) (s, err); } void timeoutcatch (); void timeoutbump (); void input (); bool rnone () { return false; } bool rline (); bool rany (); void setreadcb (bool (aios::*fn) (), rcb_t cb); void mkwcb (wcb_t cb) { if (fd >= 0) (*cb) (err); } void (output) (); void setoutcb (); void schedwrite (); void dumpdebug (); void outstart () { assert (!weof); if (debugname) { outb.tosuio ()->breakiov (); debugiov = outb.tosuio ()->iovcnt (); } } void outstop () { if (debugname) dumpdebug (); debugiov = -1; schedwrite (); } protected: aios (int, size_t); ~aios (); void finalize (); public: enum { defrbufsize = 0x2000 }; static ref alloc (int fd, size_t rbsz = defrbufsize) { return New refcounted (fd, rbsz); } int fdno () { return fd; } void setdebug (str name) { debugname = name; } void settimeout (time_t secs) { timeoutval = secs; timeoutbump (); } void abort (); void setrbufsize (size_t n) { inb.resize (n); } void readline (rcb_t cb) { setreadcb (&aios::rline, cb); } void readany (rcb_t cb) { setreadcb (&aios::rany, cb); } void unread (size_t n) { inb.unrembytes (n); } void writev (const iovec *iov, int iovcnt); void write (void *buf, size_t len) { iovec iov = { iovbase_t (buf), len }; writev (&iov, 1); } void sendeof (); void setwcb (wcb_t cb) { suio_callback (outb.tosuio (), wrap (this, &aios::mkwcb, cb)); } int flush (); void sendfd (int sfd) { fdsendq.push_back (sfd); } }; typedef ref aios_t; class aiosout : public strbuf { aios *s; // aiosout (aiosout &o) : strbuf (o), s (o.s) { o.s = NULL; } aiosout &operator= (const aiosout &); public: /* XXX - We intentionally make the copy constructor public and * undefined, because aiosout objects cannot be copied. No * reasonable compiler should copy an aiosout during reference copy * initialization (e.g., ``aout << "hello world\n";''). However, * section 8.5.3/5 of the C++ standard implies the compiler is * allowed to make copies of an aios object during reference copy * initialization, because it can make and initialize a temporary * aiosout using copy (not direct) initialization from the const * aios_t &. Section 12.1/1 therefore requires that the copy * constructor be accessible, so we can't make it private either. */ aiosout (const aiosout &o); aiosout (const aios_t &a) : strbuf (a->outb), s(a) { s->outstart (); } aiosout (const aios_t::ptr &a) : strbuf (a->outb), s(a) { s->outstart (); } ~aiosout () { s->outstop (); } }; template inline const strbuf & operator<< (const aiosout &o, const T &a) { return strbuf_cat (o, a); } inline const strbuf & operator<< (const aiosout &o, const str &s) { suio_print (o.tosuio (), s); return o; } // XXX - gcc bug requires this: inline const strbuf & operator<< (const aiosout &o, const char *a) { return strbuf_cat (o, a); } // extern const str endl; #ifndef __AIOS_IMPLEMENTATION extern aios_t ain, aout; #endif /* !__AIOS_IMPLEMENTATION */ #endif /* !_ASYNC_AIOS_H_ */