Changeset 14:3caa1d3122db in xplcommon
- Timestamp:
- 12/29/12 10:03:12 (12 years ago)
- Branch:
- default
- Phase:
- public
- Files:
-
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
TODO
r12 r14 1 - POSIX: make the Waitable Failable2 1 - POSIX: the buffered waitable should be renamed BufferedStream (or something like that), and made public -
src/xplcommon/Failable.h
r6 r14 82 82 83 83 //------------------------------------------------------------------------------ 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 */ 92 template <class Child> 93 class FailableReference 94 { 95 public: 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 //------------------------------------------------------------------------------ 84 113 // Inline definitions 85 114 //------------------------------------------------------------------------------ … … 119 148 120 149 //------------------------------------------------------------------------------ 150 //------------------------------------------------------------------------------ 151 152 template <class Child> 153 inline bool FailableReference<Child>::failed() const 154 { 155 return static_cast<const Child*>(this)->getFailable().failed(); 156 } 157 158 //------------------------------------------------------------------------------ 159 160 template <class Child> 161 inline errorCode_t FailableReference<Child>::getErrorCode() const 162 { 163 return static_cast<const Child*>(this)->getFailable().getErrorCode(); 164 } 165 166 //------------------------------------------------------------------------------ 167 168 template <class Child> 169 inline void FailableReference<Child>::repair() 170 { 171 static_cast<Child*>(this)->getFailable().repair(); 172 } 173 174 //------------------------------------------------------------------------------ 121 175 122 176 } /* namespace xplcommon */ -
src/xplcommon/Waiter.h
r7 r14 46 46 * instance is passed to them. 47 47 */ 48 class Waiter 48 class Waiter : public Failable 49 49 { 50 50 public: -
src/xplcommon/posix/Acceptor.cc
r6 r14 34 34 #include "ServerSocket.h" 35 35 36 #include <cerrno>37 38 36 #include <poll.h> 39 37 #include <sys/socket.h> … … 57 55 if (acceptedFD>=0) return true; 58 56 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); 63 60 if (result<0) { 64 if (errno==EAGAIN || errno==EWOULDBLOCK) { 61 if (socket.failed()) { 62 socket.events &= ~POLLIN; 63 } else { 65 64 socket.events |= POLLIN; 66 } else {67 socket.events &= ~POLLIN;68 setErrorCode(errno);69 65 } 70 66 return false; -
src/xplcommon/posix/Acceptor.h
r11 r14 34 34 #include "../Failable.h" 35 35 36 #include "ServerSocket.h" 37 36 38 #include <cstdlib> 37 39 … … 42 44 //------------------------------------------------------------------------------ 43 45 44 class ServerSocket;45 46 //------------------------------------------------------------------------------47 48 46 /** 49 47 * Class representing the accepting of an incoming connection on a 50 48 * socket. 51 49 */ 52 class Acceptor : public ::xplcommon::Failable 50 class Acceptor : public ::xplcommon::FailableReference<Acceptor> 53 51 { 54 52 protected: … … 106 104 */ 107 105 void connectionProcessed(); 106 107 private: 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>; 108 119 }; 109 120 … … 129 140 //------------------------------------------------------------------------------ 130 141 142 inline const ::xplcommon::Failable& Acceptor::getFailable() const 143 { 144 return socket; 145 } 146 147 //------------------------------------------------------------------------------ 148 149 inline ::xplcommon::Failable& Acceptor::getFailable() 150 { 151 return socket; 152 } 153 154 //------------------------------------------------------------------------------ 155 131 156 } /* namespace xplcommon::posix */ } /* namespace xplcommon */ 132 157 -
src/xplcommon/posix/BufferedWaitable.cc
r10 r14 68 68 ssize_t BufferedWaitable::read(void* dest, size_t length) 69 69 { 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; 71 75 } 72 76 … … 75 79 ssize_t BufferedWaitable::write(const void* src, size_t length) 76 80 { 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; 78 86 } 79 87 -
src/xplcommon/posix/BufferedWaitable.h
r10 r14 110 110 * 111 111 * @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. 113 114 */ 114 115 virtual ssize_t read(void* dest, size_t length); … … 121 122 * writing. 122 123 * 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. 124 126 */ 125 127 virtual ssize_t write(const void* src, size_t length); -
src/xplcommon/posix/ClientSocket.cc
r6 r14 36 36 #include <poll.h> 37 37 38 #include <sys/socket.h> 39 38 40 //------------------------------------------------------------------------------ 39 41 … … 72 74 //------------------------------------------------------------------------------ 73 75 76 bool 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 74 87 // Local Variables: 75 88 // mode: C++ -
src/xplcommon/posix/ClientSocket.h
r6 r14 37 37 38 38 namespace xplcommon { namespace posix { 39 40 //------------------------------------------------------------------------------ 41 42 class Connector; 39 43 40 44 //------------------------------------------------------------------------------ … … 84 88 virtual void handleEvents(short events); 85 89 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 86 100 friend class Connector; 87 101 }; -
src/xplcommon/posix/Connector.cc
r6 r14 34 34 #include "ClientSocket.h" 35 35 36 #include <cerrno>37 38 36 #include <poll.h> 39 37 #include <sys/socket.h> … … 53 51 const struct sockaddr* addr = getAddress(addrlen); 54 52 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; 63 58 } else { 64 connected = true; 59 connecting = true; 60 socket.events |= POLLOUT; 61 return false; 65 62 } 66 67 return result==0;68 63 } 69 64 … … 80 75 socklen_t len = sizeof(error); 81 76 if (getsockopt(socket.fd, SOL_SOCKET, SO_ERROR, &error, &len)<0) { 82 s etErrorCode(errno);77 socket.setErrorCodeFromErrno(); 83 78 } else { 84 79 if (error==0) { 85 80 connected = true; 86 81 } else { 87 s etErrorCode(error);82 socket.setErrorCode(error); 88 83 } 89 84 } -
src/xplcommon/posix/Connector.h
r6 r14 34 34 #include "../Failable.h" 35 35 36 #include "ClientSocket.h" 37 36 38 #include <cstdlib> 37 39 … … 46 48 //------------------------------------------------------------------------------ 47 49 48 class ClientSocket;49 50 //------------------------------------------------------------------------------51 52 50 /** 53 51 * Class representing the creation of a connection to some remote 54 52 * entity, like a socket or a pipe. 55 53 */ 56 class Connector : public Failable 54 class Connector : public FailableReference<Connector> 57 55 { 58 56 private: … … 112 110 void handleWritable(); 113 111 112 private: 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>; 114 124 friend class ClientSocket; 115 125 }; … … 128 138 //------------------------------------------------------------------------------ 129 139 140 inline const ::xplcommon::Failable& Connector::getFailable() const 141 { 142 return socket; 143 } 144 145 //------------------------------------------------------------------------------ 146 147 inline ::xplcommon::Failable& Connector::getFailable() 148 { 149 return socket; 150 } 151 152 //------------------------------------------------------------------------------ 153 130 154 } /* namespace xplcommon::posix */ } /* namespace xplcommon */ 131 155 -
src/xplcommon/posix/LocalServerSocket.cc
r13 r14 33 33 34 34 #include <cstdio> 35 #include <cerrno>36 35 37 36 #include <pwd.h> -
src/xplcommon/posix/LocalServerSocket.h
r13 r14 33 33 34 34 #include "ServerSocket.h" 35 #include "../Failable.h"36 35 37 36 #include "LocalAcceptor.h" … … 51 50 * actual socket will be created with the name /tmp/<name>-<username>. 52 51 */ 53 class LocalServerSocket : public ServerSocket , public ::xplcommon::Failable52 class LocalServerSocket : public ServerSocket 54 53 { 55 54 private: -
src/xplcommon/posix/ReadingBuffer.cc
r6 r14 34 34 #include "BufferedWaitable.h" 35 35 36 #include <cerrno>37 38 36 #include <poll.h> 39 37 … … 55 53 ssize_t result = waitable.read(getData(), getCapacity()); 56 54 if (result<0) { 57 if (errno==EAGAIN || errno==EWOULDBLOCK) { 55 if (waitable.failed()) { 56 waitable.events &= ~POLLIN; 57 } else { 58 58 waitable.events |= POLLIN; 59 } else {60 waitable.events &= ~POLLIN;61 setErrorCode(errno);62 59 } 63 60 } else { -
src/xplcommon/posix/ServerSocket.cc
r6 r14 34 34 #include "Socket.h" 35 35 36 #include <cstdio>37 38 36 #include <unistd.h> 39 37 #include <sys/socket.h> … … 49 47 Waitable(waiter, Socket::socket(domain, type, protocol)) 50 48 { 49 if (fd<0) setErrorCodeFromErrno(); 51 50 } 52 51 … … 55 54 ServerSocket::~ServerSocket() 56 55 { 57 ::close(fd);56 if (fd>=0) ::close(fd); 58 57 } 59 58 60 59 //------------------------------------------------------------------------------ 61 60 62 intServerSocket::bind(const struct sockaddr* addr, size_t addrlen,63 bool reuseaddr)61 bool ServerSocket::bind(const struct sockaddr* addr, size_t addrlen, 62 bool reuseaddr) 64 63 { 65 64 if (reuseaddr) { 66 65 int reuse = 1; 67 66 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; 70 69 } 71 70 } 72 71 73 return ::bind(fd, addr, addrlen); 72 if (::bind(fd, addr, addrlen)<0) { 73 setErrorCodeFromErrno(); 74 return false; 75 } 76 77 return true; 74 78 } 75 79 76 80 //------------------------------------------------------------------------------ 77 81 78 intServerSocket::listen(int backlog)82 bool ServerSocket::listen(int backlog) 79 83 { 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 94 int 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; 81 104 } 82 105 -
src/xplcommon/posix/ServerSocket.h
r6 r14 75 75 * @param reuseaddr if set to true, the SO_REUSEADDR socket option 76 76 * will be set. 77 * 78 * @return if the binding has succeeded. If it is false, the error 79 * code will be set accordingly. 77 80 */ 78 intbind(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); 80 83 81 84 /** 82 85 * 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. 83 89 */ 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); 85 100 86 101 friend class Acceptor; -
src/xplcommon/posix/Socket.cc
r6 r14 32 32 #include "Socket.h" 33 33 34 #include <cstdio>35 36 34 #include <unistd.h> 37 35 #include <sys/socket.h> … … 45 43 int Socket::socket(int domain, int type, int protocol) 46 44 { 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); 52 46 } 53 47 … … 56 50 Socket::~Socket() 57 51 { 58 ::close(fd);52 if (fd>=0) ::close(fd); 59 53 } 60 54 -
src/xplcommon/posix/Socket.h
r11 r14 41 41 42 42 namespace xplcommon { namespace posix { 43 44 //------------------------------------------------------------------------------45 46 class Connector;47 43 48 44 //------------------------------------------------------------------------------ … … 92 88 readingCapacity, writingCapacity) 93 89 { 90 if (fd<0) setErrorCodeFromErrno(); 94 91 } 95 92 -
src/xplcommon/posix/Waitable.h
r11 r14 32 32 //------------------------------------------------------------------------------ 33 33 34 #include "../Failable.h" 35 36 #include <cerrno> 37 38 //------------------------------------------------------------------------------ 39 34 40 namespace xplcommon { namespace posix { 35 41 … … 45 51 * It is basically a file descriptor. 46 52 */ 47 class Waitable 53 class Waitable : public Failable 48 54 { 49 55 public: … … 118 124 virtual void handleEvents(short events) = 0; 119 125 126 /** 127 * Set the error code from errno. 128 */ 129 void setErrorCodeFromErrno(); 130 120 131 friend class Waiter; 121 132 }; … … 146 157 //------------------------------------------------------------------------------ 147 158 159 inline void Waitable::setErrorCodeFromErrno() 160 { 161 setErrorCode(errno); 162 } 163 164 //------------------------------------------------------------------------------ 165 148 166 } /* namespace xplcommon::posix */ } /* namespace xplcommon */ 149 167 -
src/xplcommon/posix/WaitableBuffer.h
r6 r14 35 35 #include "../Failable.h" 36 36 37 #include "BufferedWaitable.h" 38 37 39 //------------------------------------------------------------------------------ 38 40 39 41 namespace xplcommon { namespace posix { 40 41 //------------------------------------------------------------------------------42 43 class BufferedWaitable;44 42 45 43 //------------------------------------------------------------------------------ … … 49 47 */ 50 48 class WaitableBuffer : public ::xplcommon::Buffer, 51 public ::xplcommon::Failable 49 public ::xplcommon::FailableReference<WaitableBuffer> 52 50 { 53 51 protected: … … 62 60 */ 63 61 WaitableBuffer(size_t capacity, BufferedWaitable* waitable); 62 63 private: 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>; 64 75 }; 65 76 … … 77 88 //------------------------------------------------------------------------------ 78 89 90 inline const ::xplcommon::Failable& WaitableBuffer::getFailable() const 91 { 92 return waitable; 93 } 94 95 //------------------------------------------------------------------------------ 96 97 inline ::xplcommon::Failable& WaitableBuffer::getFailable() 98 { 99 return waitable; 100 } 101 102 //------------------------------------------------------------------------------ 103 79 104 } /* namespace xplcommon::posix */ } /* namespace xplcommon */ 80 105 -
src/xplcommon/posix/WaitableEvent.cc
r8 r14 32 32 #include "WaitableEvent.h" 33 33 34 #include <cassert>35 #include <cerrno>36 #include <cstdio>37 38 34 #include <poll.h> 39 35 #include <unistd.h> … … 51 47 fired(false) 52 48 { 53 assert(fd>=0); 49 if (fd<0) { 50 setErrorCodeFromErrno(); 51 } 54 52 } 55 53 … … 68 66 if (write(fd, &one, sizeof(one))<0) { 69 67 if (errno!=EAGAIN) { 70 setErrorCode (errno);68 setErrorCodeFromErrno(); 71 69 } 72 70 } … … 111 109 if (read(fd, &value, sizeof(value))<0) { 112 110 if (errno!=EAGAIN) { 113 setErrorCode (errno);111 setErrorCodeFromErrno(); 114 112 } 115 113 } else { -
src/xplcommon/posix/WaitableEvent.h
r8 r14 45 45 * An event on which one can wait with a waiter. 46 46 */ 47 class WaitableEvent : public Waitable , public Failable47 class WaitableEvent : public Waitable 48 48 { 49 49 private: -
src/xplcommon/posix/Waiter.cc
r3 r14 35 35 36 36 #include <cassert> 37 #include <c stdio>37 #include <cerrno> 38 38 39 39 //------------------------------------------------------------------------------ … … 114 114 115 115 if (result<0) { 116 perror("xplcommon::posix::Waiter::wait: poll");116 setErrorCode(errno); 117 117 return false; 118 118 } else if (result>0) { -
src/xplcommon/posix/Waiter.h
r3 r14 32 32 //------------------------------------------------------------------------------ 33 33 34 #include "../Failable.h" 35 34 36 #include <map> 35 37 … … 52 54 * for them. 53 55 */ 54 class Waiter 56 class Waiter : public Failable 55 57 { 56 58 private: -
src/xplcommon/posix/WritingBuffer.cc
r6 r14 34 34 #include "BufferedWaitable.h" 35 35 36 #include <cerrno>37 38 36 #include <poll.h> 39 37 … … 66 64 ssize_t result = waitable.write(getData() + offset, toWrite); 67 65 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 { 69 69 waitable.events |= POLLOUT; 70 70 if (result>0) offset += result; 71 } else {72 waitable.events &= ~POLLOUT;73 setErrorCode(errno);74 71 } 75 72 return false;
Note:
See TracChangeset
for help on using the changeset viewer.