[17] | 1 | /*! \mainpage Very Simple Cross-Platform Library Documentation
|
---|
| 2 | *
|
---|
| 3 | * \section intro Introduction
|
---|
| 4 | *
|
---|
| 5 | * VSCPL is a simple library containing some useful classes related to
|
---|
| 6 | * thread handling and I/O for POSIX and Windows systems. It is
|
---|
| 7 | * intended to be extended eventually, but has been written chiefly
|
---|
| 8 | * for the X-Plane Remote Access plugin and its client libraries,
|
---|
| 9 | * which is reflected by the rather minimal functionality.
|
---|
| 10 | *
|
---|
| 11 | * To avoid namespace clashes, the classes of the library are put in
|
---|
| 12 | * the \c hu::varadiistvan::scpl namespace or children of it.
|
---|
| 13 | *
|
---|
| 14 | * \subsection threading Threading
|
---|
| 15 | *
|
---|
| 16 | * The usual \ref hu::varadiistvan::scpl::Thread "thread" class and
|
---|
| 17 | * some threading primitives are provided:
|
---|
| 18 | * \ref hu::varadiistvan::scpl::Mutex "mutexes" and
|
---|
| 19 | * \ref hu::varadiistvan::scpl::CondVar "conditional variables".
|
---|
| 20 | *
|
---|
| 21 | * \subsection io Input/Output
|
---|
| 22 | *
|
---|
| 23 | * The I/O parts are somewhat generic, but currently support
|
---|
| 24 | * communication via so-called "local" sockets, which are Unix sockets
|
---|
| 25 | * on POSIX and named pipes on Windows. Of course, a common interface
|
---|
| 26 | * is provided, so the actual details are hidden.
|
---|
| 27 | *
|
---|
| 28 | * Input/output handling is based on the notion of a thread waiting
|
---|
| 29 | * for one or more I/O events and then handling them. For this purpose
|
---|
| 30 | * an instance of the \ref hu::varadiistvan::scpl::io::Waiter class
|
---|
| 31 | * should be created and then this instance should be passed to the
|
---|
| 32 | * instances of other classes. Waiting can be accomplished by calling
|
---|
| 33 | * its \ref hu::varadiistvan::scpl::io::Waiter::wait "wait" function
|
---|
| 34 | * and optionally passing a timeout.
|
---|
| 35 | *
|
---|
| 36 | * A local server socket can be created by instantiation the
|
---|
| 37 | * \ref hu::varadiistvan::scpl::io::LocalServerSocket class. Besides
|
---|
| 38 | * the waiter, it is given a name. It is ensured that if several users
|
---|
| 39 | * of the computer run programs using the same name, each will see
|
---|
| 40 | * their own socket.
|
---|
| 41 | *
|
---|
| 42 | * A server socket needs to accept incoming connections. For this
|
---|
| 43 | * purpose and \ref hu::varadiistvan::scpl::io::LocalAcceptor
|
---|
| 44 | * "acceptor" instance is used, which can be acquired by calling the
|
---|
| 45 | * \ref hu::varadiistvan::scpl::io::LocalServerSocket::getAcceptor
|
---|
| 46 | * "getAcceptor" function. To check, if there is an incoming
|
---|
| 47 | * connection, call the acceptor's
|
---|
| 48 | * \ref hu::varadiistvan::scpl::io::LocalAcceptor::accept "accept"
|
---|
| 49 | * function. It returns immediately with a boolean telling whether
|
---|
| 50 | * there is a connection. If so, you should call the
|
---|
| 51 | * \ref hu::varadiistvan::scpl::io::LocalAcceptor::getSocket
|
---|
| 52 | * "getSocket" function to get the socket representing the connection.
|
---|
| 53 | * If there is no incoming connection, you can wait for one using the
|
---|
| 54 | * waiter. Note, that
|
---|
| 55 | * \ref hu::varadiistvan::scpl::io::LocalAcceptor::accept "accept"
|
---|
| 56 | * should be called once unsuccessfully before trying to wait,
|
---|
| 57 | * otherwise it is not guaranteed that waiting will finish if a new
|
---|
| 58 | * connection comes in.
|
---|
| 59 | *
|
---|
| 60 | * \c LocalAcceptor is a subclass of
|
---|
| 61 | * \ref hu::varadiistvan::scpl::io::Failable "Failable", which can be
|
---|
| 62 | * used to check if some error occured. If \c accept returns \c false,
|
---|
| 63 | * it should be check if the failure of accepting is due to an error,
|
---|
| 64 | * or is caused simply by no client wanting to connect.
|
---|
| 65 | *
|
---|
| 66 | * A local client socket is created by instantiation
|
---|
| 67 | * \ref hu::varadiistvan::scpl::io::LocalClientSocket. It receives the
|
---|
| 68 | * same name as the server socket to which we want to
|
---|
| 69 | * connect. Similarly to accepting a connection on a server socket,
|
---|
| 70 | * the client socket's
|
---|
| 71 | * \ref hu::varadiistvan::scpl::io::LocalClientSocket::getConnector
|
---|
| 72 | * "getConnector" should be called to retrieve a
|
---|
| 73 | * \ref hu::varadiistvan::scpl::io::LocalConnector "LocalConnector"
|
---|
| 74 | * instance. Its
|
---|
| 75 | * \ref hu::varadiistvan::scpl::io::LocalConnector::connect "connect"
|
---|
| 76 | * member function should be called to initiate the connection. If it
|
---|
| 77 | * returns \c true, the connection has succeeded. Otherwise one can
|
---|
| 78 | * wait using the socket's waiter for the connection to succeed. If
|
---|
| 79 | * waiting finishes, \c connect can be called again to check, if the
|
---|
| 80 | * connection has been established. In case of a \c false return
|
---|
| 81 | * value, the error condition should be checked here as well.
|
---|
| 82 | *
|
---|
| 83 | * Once the connection has been established, the actual communication
|
---|
| 84 | * can begin. Both \c LocalSocket and \c LocalClientSocket are
|
---|
| 85 | * subclasses of
|
---|
| 86 | * \ref hu::varadiistvan::scpl::io::BufferedStream "BufferedStream".
|
---|
| 87 | * It can be used to acquire an instance of
|
---|
| 88 | * \ref hu::varadiistvan::scpl::io::ReadingBuffer "ReadingBuffer" for
|
---|
| 89 | * reading, and an instance of
|
---|
| 90 | * \ref hu::varadiistvan::scpl::io::WritingBuffer "WritingBuffer" for
|
---|
| 91 | * writing.
|
---|
| 92 | *
|
---|
| 93 | * To read, call the
|
---|
| 94 | * \ref hu::varadiistvan::scpl::io::ReadingBuffer::read "read"
|
---|
| 95 | * function. It returns \c true, if reading has succeeded, \c false
|
---|
| 96 | * otherwise which may indicate an error condition or simply the fact
|
---|
| 97 | * that nothing has been received yet, in which case the program can
|
---|
| 98 | * wait using the \c Waiter. If data has been read, it can be accessed
|
---|
| 99 | * by the buffer's methods inherited from
|
---|
| 100 | * \ref hu::varadiistvan::scpl::io::Buffer "Buffer". Before reading
|
---|
| 101 | * again, the buffer's
|
---|
| 102 | * \ref hu::varadiistvan::scpl::io::Buffer::reset "reset" function
|
---|
| 103 | * should be called, otherwise \c read just returns \c true and
|
---|
| 104 | * nothing happens.
|
---|
| 105 | *
|
---|
| 106 | * To write, put data into the writing buffer and call its
|
---|
| 107 | * \ref hu::varadiistvan::scpl::io::WritingBuffer::write "write"
|
---|
| 108 | * function. If all data in the buffer could be written, it returns
|
---|
| 109 | * \c true, otherwise \c false, which, again, might indicate error,
|
---|
| 110 | * but also the fact that not all data could be written. In this case,
|
---|
| 111 | * the program can wait, and then retry writing again, and do this
|
---|
| 112 | * until finally \c write returns \c true. If writing succeeds, the
|
---|
| 113 | * buffer is reset automatically, and one can put new data into it.
|
---|
| 114 | *
|
---|
| 115 | * The facilities described above provide for asynchronous,
|
---|
| 116 | * event-based stream handling, which is perfect for programs or
|
---|
| 117 | * threads that should work with several streams, timeouts and
|
---|
| 118 | * possibly other events simultaneously. This is, however, not always
|
---|
| 119 | * the case. It might very well be that one thread is dedicated to
|
---|
| 120 | * just deal with one stream only or at least with one stream at a
|
---|
| 121 | * time. In such a case this hocus-pocus with always (re)trying
|
---|
| 122 | * operations and waiting can be very cumbersome. It would be much
|
---|
| 123 | * better to just call a function to read or write, which would return
|
---|
| 124 | * only, if the requested operation has completed.
|
---|
| 125 | *
|
---|
| 126 | * This is provided by the
|
---|
| 127 | * \ref hu::varadiistvan::scpl::io::BlockingStream class. Its
|
---|
| 128 | * constructor receives and instance of \c BufferedStream, and it
|
---|
| 129 | * provides blocking read, write and flushing operations. It also has
|
---|
| 130 | * a \ref hu::varadiistvan::scpl::io::BlockingStream::interrupt "interrupt"
|
---|
| 131 | * function, which can be called from another thread. If the stream is
|
---|
| 132 | * blocking on an operation, that operation will then return with \c
|
---|
| 133 | * false, and the interrupted condition can the be
|
---|
| 134 | * \ref hu::varadiistvan::scpl::io::BlockingStream::isInterrupted
|
---|
| 135 | * "checked".
|
---|
| 136 | *
|
---|
| 137 | * \c BlockingStream has a subclass called
|
---|
| 138 | * \ref hu::varadiistvan::scpl::io::DataStream "DataStream", which can
|
---|
| 139 | * be used to read and write values of the primitive data types. The
|
---|
| 140 | * endianness is that of the processor, i.e. no conversion is made to
|
---|
| 141 | * a common one.
|
---|
| 142 | */
|
---|