Changeset 14:3caa1d3122db in xplcommon


Ignore:
Timestamp:
12/29/12 10:03:12 (12 years ago)
Author:
István Váradi <ivaradi@…>
Branch:
default
Phase:
public
Message:

Moved the storage of the error code to where it belongs

Files:
25 edited

Legend:

Unmodified
Added
Removed
  • TODO

    r12 r14  
    1 - POSIX: make the Waitable Failable
    21- POSIX: the buffered waitable should be renamed BufferedStream (or something like that), and made public
  • src/xplcommon/Failable.h

    r6 r14  
    8282
    8383//------------------------------------------------------------------------------
     84
     85/**
     86 * An object that references another failable object and fails
     87 * together with that object.
     88 *
     89 * The Child class should contain a function named getFailable()
     90 * which returns the failable object.
     91 */
     92template <class Child>
     93class FailableReference
     94{
     95public:
     96    /**
     97     * Indicate if the referenced object has failed.
     98     */
     99    bool failed() const;
     100
     101    /**
     102     * Get the error code from the referenced object.
     103     */
     104    errorCode_t getErrorCode() const;
     105
     106    /**
     107     * Discard the error code of the referenced object.
     108     */
     109    void repair();
     110};
     111
     112//------------------------------------------------------------------------------
    84113// Inline definitions
    85114//------------------------------------------------------------------------------
     
    119148
    120149//------------------------------------------------------------------------------
     150//------------------------------------------------------------------------------
     151
     152template <class Child>
     153inline bool FailableReference<Child>::failed() const
     154{
     155    return static_cast<const Child*>(this)->getFailable().failed();
     156}
     157
     158//------------------------------------------------------------------------------
     159
     160template <class Child>
     161inline errorCode_t FailableReference<Child>::getErrorCode() const
     162{
     163    return static_cast<const Child*>(this)->getFailable().getErrorCode();
     164}
     165
     166//------------------------------------------------------------------------------
     167
     168template <class Child>
     169inline void FailableReference<Child>::repair()
     170{
     171    static_cast<Child*>(this)->getFailable().repair();
     172}
     173
     174//------------------------------------------------------------------------------
    121175
    122176} /* namespace xplcommon */
  • src/xplcommon/Waiter.h

    r7 r14  
    4646 * instance is passed to them.
    4747 */
    48 class Waiter
     48class Waiter : public Failable
    4949{
    5050public:
  • src/xplcommon/posix/Acceptor.cc

    r6 r14  
    3434#include "ServerSocket.h"
    3535
    36 #include <cerrno>
    37 
    3836#include <poll.h>
    3937#include <sys/socket.h>
     
    5755    if (acceptedFD>=0) return true;
    5856
    59     socklen_t addrlen = addressLength;
    60     int result = ::accept(socket.fd,
    61                           reinterpret_cast<struct ::sockaddr*>(address),
    62                           &addrlen);
     57    size_t addrlen = addressLength;
     58    int result = socket.accept(reinterpret_cast<struct ::sockaddr*>(address),
     59                               (address==0) ? 0 : &addrlen);
    6360    if (result<0) {
    64         if (errno==EAGAIN || errno==EWOULDBLOCK) {
     61        if (socket.failed()) {
     62            socket.events &= ~POLLIN;
     63        } else {
    6564            socket.events |= POLLIN;
    66         } else {
    67             socket.events &= ~POLLIN;
    68             setErrorCode(errno);
    6965        }
    7066        return false;
  • src/xplcommon/posix/Acceptor.h

    r11 r14  
    3434#include "../Failable.h"
    3535
     36#include "ServerSocket.h"
     37
    3638#include <cstdlib>
    3739
     
    4244//------------------------------------------------------------------------------
    4345
    44 class ServerSocket;
    45 
    46 //------------------------------------------------------------------------------
    47 
    4846/**
    4947 * Class representing the accepting of an incoming connection on a
    5048 * socket.
    5149 */
    52 class Acceptor : public ::xplcommon::Failable
     50class Acceptor : public ::xplcommon::FailableReference<Acceptor>
    5351{
    5452protected:
     
    106104     */
    107105    void connectionProcessed();
     106
     107private:
     108    /**
     109     * Get the failable object.
     110     */
     111    const ::xplcommon::Failable& getFailable() const;
     112
     113    /**
     114     * Get the failable object.
     115     */
     116    ::xplcommon::Failable& getFailable();
     117
     118    friend class FailableReference<Acceptor>;
    108119};
    109120
     
    129140//------------------------------------------------------------------------------
    130141
     142inline const ::xplcommon::Failable& Acceptor::getFailable() const
     143{
     144    return socket;
     145}
     146
     147//------------------------------------------------------------------------------
     148
     149inline ::xplcommon::Failable& Acceptor::getFailable()
     150{
     151    return socket;
     152}
     153
     154//------------------------------------------------------------------------------
     155
    131156} /* namespace xplcommon::posix */ } /* namespace xplcommon */
    132157
  • src/xplcommon/posix/BufferedWaitable.cc

    r10 r14  
    6868ssize_t BufferedWaitable::read(void* dest, size_t length)
    6969{
    70     return ::read(fd, dest, length);
     70    ssize_t result = ::read(fd, dest, length);
     71    if (result<0 && errno!=EAGAIN && errno!=EWOULDBLOCK) {
     72        setErrorCodeFromErrno();
     73    }
     74    return result;
    7175}
    7276
     
    7579ssize_t BufferedWaitable::write(const void* src, size_t length)
    7680{
    77     return ::write(fd, src, length);
     81    ssize_t result = ::write(fd, src, length);
     82    if (result<0 && errno!=EAGAIN && errno!=EWOULDBLOCK) {
     83        setErrorCodeFromErrno();
     84    }
     85    return result;
    7886}
    7987
  • src/xplcommon/posix/BufferedWaitable.h

    r10 r14  
    110110     *
    111111     * @return the number of bytes read (0 in case of end-of-file or
    112      * when the connection is closed), -1 on error.
     112     * when the connection is closed), -1 on error. In case of error,
     113     * the error code will be set up.
    113114     */
    114115    virtual ssize_t read(void* dest, size_t length);
     
    121122     * writing.
    122123     *
    123      * @return the number of bytes written, or -1 on error.
     124     * @return the number of bytes written, or -1 on error. In case of error,
     125     * the error code will be set up.
    124126     */
    125127    virtual ssize_t write(const void* src, size_t length);
  • src/xplcommon/posix/ClientSocket.cc

    r6 r14  
    3636#include <poll.h>
    3737
     38#include <sys/socket.h>
     39
    3840//------------------------------------------------------------------------------
    3941
     
    7274//------------------------------------------------------------------------------
    7375
     76bool ClientSocket::connect(const struct sockaddr* addr, size_t addrlen)
     77{
     78    int result = ::connect(fd, addr, addrlen);
     79    if (result<0 && errno!=EINPROGRESS) {
     80        setErrorCodeFromErrno();
     81    }
     82    return result>=0;
     83}
     84
     85//------------------------------------------------------------------------------
     86
    7487// Local Variables:
    7588// mode: C++
  • src/xplcommon/posix/ClientSocket.h

    r6 r14  
    3737
    3838namespace xplcommon { namespace posix {
     39
     40//------------------------------------------------------------------------------
     41
     42class Connector;
    3943
    4044//------------------------------------------------------------------------------
     
    8488    virtual void handleEvents(short events);
    8589
     90    /**
     91     * Connect the socket to the given address.
     92     *
     93     * @return whether the connection succeeded or not. If it does not
     94     * succeeded, it may be either because of the socket being
     95     * non-blocking and some time is needed, or because of a failure,
     96     * in which case the error code will be set properly.
     97     */
     98    bool connect(const struct sockaddr* addr, size_t addrlen);
     99
    86100    friend class Connector;
    87101};
  • src/xplcommon/posix/Connector.cc

    r6 r14  
    3434#include "ClientSocket.h"
    3535
    36 #include <cerrno>
    37 
    3836#include <poll.h>
    3937#include <sys/socket.h>
     
    5351    const struct sockaddr* addr = getAddress(addrlen);
    5452
    55     int result = ::connect(socket.fd, addr, addrlen);
    56     if (result<0) {
    57         if (errno==EINPROGRESS) {
    58             connecting = true;
    59             socket.events |= POLLOUT;
    60         } else {
    61             setErrorCode(errno);
    62         }
     53    if (socket.connect(addr, addrlen)) {
     54        connected = true;
     55        return true;
     56    } else if (socket.failed()) {
     57        return false;
    6358    } else {
    64         connected = true;
     59        connecting = true;
     60        socket.events |= POLLOUT;
     61        return false;
    6562    }
    66 
    67     return result==0;
    6863}
    6964
     
    8075    socklen_t len = sizeof(error);
    8176    if (getsockopt(socket.fd, SOL_SOCKET, SO_ERROR, &error, &len)<0) {
    82         setErrorCode(errno);
     77        socket.setErrorCodeFromErrno();
    8378    } else {
    8479        if (error==0) {
    8580            connected = true;
    8681        } else {
    87             setErrorCode(error);
     82            socket.setErrorCode(error);
    8883        }
    8984    }
  • src/xplcommon/posix/Connector.h

    r6 r14  
    3434#include "../Failable.h"
    3535
     36#include "ClientSocket.h"
     37
    3638#include <cstdlib>
    3739
     
    4648//------------------------------------------------------------------------------
    4749
    48 class ClientSocket;
    49 
    50 //------------------------------------------------------------------------------
    51 
    5250/**
    5351 * Class representing the creation of a connection to some remote
    5452 * entity, like a socket or a pipe.
    5553 */
    56 class Connector : public Failable
     54class Connector : public FailableReference<Connector>
    5755{
    5856private:
     
    112110    void handleWritable();
    113111
     112private:
     113    /**
     114     * Get the failable object.
     115     */
     116    const ::xplcommon::Failable& getFailable() const;
     117
     118    /**
     119     * Get the failable object.
     120     */
     121    ::xplcommon::Failable& getFailable();
     122
     123    friend class FailableReference<Connector>;
    114124    friend class ClientSocket;
    115125};
     
    128138//------------------------------------------------------------------------------
    129139
     140inline const ::xplcommon::Failable& Connector::getFailable() const
     141{
     142    return socket;
     143}
     144
     145//------------------------------------------------------------------------------
     146
     147inline ::xplcommon::Failable& Connector::getFailable()
     148{
     149    return socket;
     150}
     151
     152//------------------------------------------------------------------------------
     153
    130154} /* namespace xplcommon::posix */ } /* namespace xplcommon */
    131155
  • src/xplcommon/posix/LocalServerSocket.cc

    r13 r14  
    3333
    3434#include <cstdio>
    35 #include <cerrno>
    3635
    3736#include <pwd.h>
  • src/xplcommon/posix/LocalServerSocket.h

    r13 r14  
    3333
    3434#include "ServerSocket.h"
    35 #include "../Failable.h"
    3635
    3736#include "LocalAcceptor.h"
     
    5150 * actual socket will be created with the name /tmp/<name>-<username>.
    5251 */
    53 class LocalServerSocket : public ServerSocket, public ::xplcommon::Failable
     52class LocalServerSocket : public ServerSocket
    5453{
    5554private:
  • src/xplcommon/posix/ReadingBuffer.cc

    r6 r14  
    3434#include "BufferedWaitable.h"
    3535
    36 #include <cerrno>
    37 
    3836#include <poll.h>
    3937
     
    5553    ssize_t result = waitable.read(getData(), getCapacity());
    5654    if (result<0) {
    57         if (errno==EAGAIN || errno==EWOULDBLOCK) {
     55        if (waitable.failed()) {
     56            waitable.events &= ~POLLIN;
     57        } else {
    5858            waitable.events |= POLLIN;
    59         } else {
    60             waitable.events &= ~POLLIN;
    61             setErrorCode(errno);
    6259        }
    6360    } else {
  • src/xplcommon/posix/ServerSocket.cc

    r6 r14  
    3434#include "Socket.h"
    3535
    36 #include <cstdio>
    37 
    3836#include <unistd.h>
    3937#include <sys/socket.h>
     
    4947    Waitable(waiter, Socket::socket(domain, type, protocol))
    5048{
     49    if (fd<0) setErrorCodeFromErrno();
    5150}
    5251
     
    5554ServerSocket::~ServerSocket()
    5655{
    57     ::close(fd);
     56    if (fd>=0) ::close(fd);
    5857}
    5958
    6059//------------------------------------------------------------------------------
    6160
    62 int ServerSocket::bind(const struct sockaddr* addr, size_t addrlen,
    63                        bool reuseaddr)
     61bool ServerSocket::bind(const struct sockaddr* addr, size_t addrlen,
     62                        bool reuseaddr)
    6463{
    6564    if (reuseaddr) {
    6665        int reuse = 1;
    6766        if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse))<0) {
    68             perror("xplcommon::posix::Socket::bind: setsockopt");
    69             return -1;
     67            setErrorCodeFromErrno();
     68            return false;
    7069        }
    7170    }
    7271
    73     return ::bind(fd, addr, addrlen);
     72    if (::bind(fd, addr, addrlen)<0) {
     73        setErrorCodeFromErrno();
     74        return false;
     75    }
     76
     77    return true;
    7478}
    7579
    7680//------------------------------------------------------------------------------
    7781
    78 int ServerSocket::listen(int backlog)
     82bool ServerSocket::listen(int backlog)
    7983{
    80     return ::listen(fd, backlog);
     84    if (::listen(fd, backlog)<0) {
     85        setErrorCodeFromErrno();
     86        return false;
     87    } else {
     88        return true;
     89    }
     90}
     91
     92//------------------------------------------------------------------------------
     93
     94int ServerSocket::accept(struct sockaddr* addr, size_t* addrlen)
     95{
     96    socklen_t alen = (addrlen==0) ? 0 : *addrlen;
     97    int result = ::accept(fd, addr, (addrlen==0) ? 0 : &alen);
     98    if (result<0 && errno!=EAGAIN && errno!=EWOULDBLOCK) {
     99        setErrorCodeFromErrno();
     100    } else {
     101        if (addrlen!=0) *addrlen = alen;
     102    }
     103    return result;
    81104}
    82105
  • src/xplcommon/posix/ServerSocket.h

    r6 r14  
    7575     * @param reuseaddr if set to true, the SO_REUSEADDR socket option
    7676     * will be set.
     77     *
     78     * @return if the binding has succeeded. If it is false, the error
     79     * code will be set accordingly.
    7780     */
    78     int bind(const struct sockaddr* addr, size_t addrlen,
    79              bool reuseaddr = true);
     81    bool bind(const struct sockaddr* addr, size_t addrlen,
     82              bool reuseaddr = true);
    8083
    8184    /**
    8285     * Start listening on the socket.
     86     *
     87     * @return if the call has succeeded. If it is false, the error
     88     * code will be set accordingly.
    8389     */
    84     int listen(int backlog = 5);
     90    bool listen(int backlog = 5);
     91
     92    /**
     93     * Accept a socket.
     94     *
     95     * @return the accepted socket. If may be -1, if the socket is
     96     * non-blocking, and no connection is available yet, or if another
     97     * error occured, in which case the error code will be set properly.
     98     */
     99    int accept(struct sockaddr* addr, size_t* addrlen);
    85100
    86101    friend class Acceptor;
  • src/xplcommon/posix/Socket.cc

    r6 r14  
    3232#include "Socket.h"
    3333
    34 #include <cstdio>
    35 
    3634#include <unistd.h>
    3735#include <sys/socket.h>
     
    4543int Socket::socket(int domain, int type, int protocol)
    4644{
    47     int fd = ::socket(domain, type, protocol);
    48     if (fd<0) {
    49         perror("xplcommon::posix::Socket::socket: socket");
    50     }
    51     return fd;
     45    return ::socket(domain, type, protocol);
    5246}
    5347
     
    5650Socket::~Socket()
    5751{
    58     ::close(fd);
     52    if (fd>=0) ::close(fd);
    5953}
    6054
  • src/xplcommon/posix/Socket.h

    r11 r14  
    4141
    4242namespace xplcommon { namespace posix {
    43 
    44 //------------------------------------------------------------------------------
    45 
    46 class Connector;
    4743
    4844//------------------------------------------------------------------------------
     
    9288                     readingCapacity, writingCapacity)
    9389{
     90    if (fd<0) setErrorCodeFromErrno();
    9491}
    9592
  • src/xplcommon/posix/Waitable.h

    r11 r14  
    3232//------------------------------------------------------------------------------
    3333
     34#include "../Failable.h"
     35
     36#include <cerrno>
     37
     38//------------------------------------------------------------------------------
     39
    3440namespace xplcommon { namespace posix {
    3541
     
    4551 * It is basically a file descriptor.
    4652 */
    47 class Waitable
     53class Waitable : public Failable
    4854{
    4955public:
     
    118124    virtual void handleEvents(short events) = 0;
    119125
     126    /**
     127     * Set the error code from errno.
     128     */
     129    void setErrorCodeFromErrno();
     130
    120131    friend class Waiter;
    121132};
     
    146157//------------------------------------------------------------------------------
    147158
     159inline void Waitable::setErrorCodeFromErrno()
     160{
     161    setErrorCode(errno);
     162}
     163
     164//------------------------------------------------------------------------------
     165
    148166} /* namespace xplcommon::posix */ } /* namespace xplcommon */
    149167
  • src/xplcommon/posix/WaitableBuffer.h

    r6 r14  
    3535#include "../Failable.h"
    3636
     37#include "BufferedWaitable.h"
     38
    3739//------------------------------------------------------------------------------
    3840
    3941namespace xplcommon { namespace posix {
    40 
    41 //------------------------------------------------------------------------------
    42 
    43 class BufferedWaitable;
    4442
    4543//------------------------------------------------------------------------------
     
    4947 */
    5048class WaitableBuffer : public ::xplcommon::Buffer,
    51                        public ::xplcommon::Failable
     49                       public ::xplcommon::FailableReference<WaitableBuffer>
    5250{
    5351protected:
     
    6260     */
    6361    WaitableBuffer(size_t capacity, BufferedWaitable* waitable);
     62
     63private:
     64    /**
     65     * Get the failable object.
     66     */
     67    const ::xplcommon::Failable& getFailable() const;
     68
     69    /**
     70     * Get the failable object.
     71     */
     72    ::xplcommon::Failable& getFailable();
     73
     74    friend class FailableReference<WaitableBuffer>;
    6475};
    6576
     
    7788//------------------------------------------------------------------------------
    7889
     90inline const ::xplcommon::Failable& WaitableBuffer::getFailable() const
     91{
     92    return waitable;
     93}
     94
     95//------------------------------------------------------------------------------
     96
     97inline ::xplcommon::Failable& WaitableBuffer::getFailable()
     98{
     99    return waitable;
     100}
     101
     102//------------------------------------------------------------------------------
     103
    79104} /* namespace xplcommon::posix */ } /* namespace xplcommon */
    80105
  • src/xplcommon/posix/WaitableEvent.cc

    r8 r14  
    3232#include "WaitableEvent.h"
    3333
    34 #include <cassert>
    35 #include <cerrno>
    36 #include <cstdio>
    37 
    3834#include <poll.h>
    3935#include <unistd.h>
     
    5147    fired(false)
    5248{
    53     assert(fd>=0);
     49    if (fd<0) {
     50        setErrorCodeFromErrno();
     51    }
    5452}
    5553
     
    6866    if (write(fd, &one, sizeof(one))<0) {
    6967        if (errno!=EAGAIN) {
    70             setErrorCode(errno);
     68            setErrorCodeFromErrno();
    7169        }
    7270    }
     
    111109    if (read(fd, &value, sizeof(value))<0) {
    112110        if (errno!=EAGAIN) {
    113             setErrorCode(errno);
     111            setErrorCodeFromErrno();
    114112        }
    115113    } else {
  • src/xplcommon/posix/WaitableEvent.h

    r8 r14  
    4545 * An event on which one can wait with a waiter.
    4646 */
    47 class WaitableEvent : public Waitable, public Failable
     47class WaitableEvent : public Waitable
    4848{
    4949private:
  • src/xplcommon/posix/Waiter.cc

    r3 r14  
    3535
    3636#include <cassert>
    37 #include <cstdio>
     37#include <cerrno>
    3838
    3939//------------------------------------------------------------------------------
     
    114114
    115115    if (result<0) {
    116         perror("xplcommon::posix::Waiter::wait: poll");
     116        setErrorCode(errno);
    117117        return false;
    118118    } else if (result>0) {
  • src/xplcommon/posix/Waiter.h

    r3 r14  
    3232//------------------------------------------------------------------------------
    3333
     34#include "../Failable.h"
     35
    3436#include <map>
    3537
     
    5254 * for them.
    5355 */
    54 class Waiter
     56class Waiter : public Failable
    5557{
    5658private:
  • src/xplcommon/posix/WritingBuffer.cc

    r6 r14  
    3434#include "BufferedWaitable.h"
    3535
    36 #include <cerrno>
    37 
    3836#include <poll.h>
    3937
     
    6664    ssize_t result = waitable.write(getData() + offset, toWrite);
    6765    if (result<static_cast<ssize_t>(toWrite)) {
    68         if (result>=0 || errno==EAGAIN || errno==EWOULDBLOCK) {
     66        if (result<0 && waitable.failed()) {
     67            waitable.events &= ~POLLOUT;
     68        } else {
    6969            waitable.events |= POLLOUT;
    7070            if (result>0) offset += result;
    71         } else {
    72             waitable.events &= ~POLLOUT;
    73             setErrorCode(errno);
    7471        }
    7572        return false;
Note: See TracChangeset for help on using the changeset viewer.