00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018 #ifndef _OASYS_IO_H_
00019 #define _OASYS_IO_H_
00020
00021 #include <fcntl.h>
00022 #include <stdlib.h>
00023 #include <sys/poll.h>
00024 #include <sys/uio.h>
00025 #include <sys/socket.h>
00026 #include <sys/stat.h>
00027
00028 #include "../debug/DebugUtils.h"
00029 #include "../thread/Notifier.h"
00030
00031 namespace oasys {
00032
00033 class IOMonitor;
00034
00041 enum IOTimeoutReturn_t {
00042 IOEOF = 0,
00043 IOERROR = -1,
00044 IOTIMEOUT = -2,
00045 IOINTR = -3,
00046 IOAGAIN = -4,
00047 IORATELIMIT = -5,
00048 };
00049
00050
00051 struct IO {
00053 enum IO_Op_t {
00054 READV = 1,
00055 RECV,
00056 RECVFROM,
00057 RECVMSG,
00058 WRITEV,
00059 SEND,
00060 SENDTO,
00061 SENDMSG,
00062
00063 CONNECT,
00064 ACCEPT,
00065 };
00066
00070 static const char* ioerr2str(int err);
00071
00073
00074 static int open(const char* path, int flags,
00075 int* errnop = 0, const char* log = 0);
00076
00077 static int open(const char* path, int flags, mode_t mode,
00078 int* errnop = 0, const char* log = 0);
00079
00080 static int close(int fd,
00081 const char* log = 0,
00082 const char* filename = "");
00083
00084 static int unlink(const char* path,
00085 const char* log = 0);
00086
00087 static int lseek(int fd, off_t offset, int whence,
00088 const char* log = 0);
00089
00090 static int truncate(int fd, off_t length,
00091 const char* log = 0);
00092
00093 static int mkstemp(char* templ, const char* log = 0);
00094
00095 static int stat(const char* path, struct stat* buf, const char* log = 0);
00096
00097 static int lstat(const char* path, struct stat* buf, const char* log = 0);
00099
00101 static int read(int fd, char* bp, size_t len,
00102 Notifier* intr = 0, const char* log = 0);
00103
00104 static int readv(int fd, const struct iovec* iov, int iovcnt,
00105 Notifier* intr = 0, const char* log = 0);
00106
00107 static int readall(int fd, char* bp, size_t len,
00108 Notifier* intr = 0, const char* log = 0);
00109
00110 static int readvall(int fd, const struct iovec* iov, int iovcnt,
00111 Notifier* intr = 0, const char* log = 0);
00112
00113 static int timeout_read(int fd, char* bp, size_t len, int timeout_ms,
00114 Notifier* intr = 0, const char* log = 0);
00115
00116 static int timeout_readv(int fd, const struct iovec* iov, int iovcnt,
00117 int timeout_ms, Notifier* intr = 0,
00118 const char* log = 0);
00119
00120 static int timeout_readall(int fd, char* bp, size_t len, int timeout_ms,
00121 Notifier* intr = 0, const char* log = 0);
00122
00123 static int timeout_readvall(int fd, const struct iovec* iov, int iovcnt,
00124 int timeout_ms, Notifier* intr = 0,
00125 const char* log = 0);
00126
00127 static int recv(int fd, char* bp, size_t len, int flags,
00128 Notifier* intr = 0, const char* log = 0);
00129
00130 static int recvfrom(int fd, char* bp, size_t len,
00131 int flags, struct sockaddr* from, socklen_t* fromlen,
00132 Notifier* intr = 0, const char* log = 0);
00133
00134 static int recvmsg(int fd, struct msghdr* msg, int flags,
00135 Notifier* intr = 0, const char* log = 0);
00136
00137 static int write(int fd, const char* bp, size_t len,
00138 Notifier* intr = 0, const char* log = 0);
00139
00140 static int writev(int fd, const struct iovec* iov, int iovcnt,
00141 Notifier* intr = 0, const char* log = 0);
00142
00143 static int writeall(int fd, const char* bp, size_t len,
00144 Notifier* intr = 0, const char* log = 0);
00145
00146 static int writevall(int fd, const struct iovec* iov, int iovcnt,
00147 Notifier* intr = 0, const char* log = 0);
00148
00149 static int timeout_write(int fd, const char* bp, size_t len, int timeout_ms,
00150 Notifier* intr = 0, const char* log = 0);
00151
00152 static int timeout_writev(int fd, const struct iovec* iov, int iovcnt,
00153 int timeout_ms, Notifier* intr = 0,
00154 const char* log = 0);
00155
00156 static int timeout_writeall(int fd, const char* bp, size_t len,
00157 int timeout_ms,
00158 Notifier* intr = 0, const char* log = 0);
00159
00160 static int timeout_writevall(int fd, const struct iovec* iov, int iovcnt,
00161 int timeout_ms, Notifier* intr = 0,
00162 const char* log = 0);
00163
00164 static int send(int fd, const char* bp, size_t len, int flags,
00165 Notifier* intr = 0, const char* log = 0);
00166
00167 static int sendto(int fd, char* bp, size_t len,
00168 int flags, const struct sockaddr* to, socklen_t tolen,
00169 Notifier* intr = 0, const char* log = 0);
00170
00171 static int sendmsg(int fd, const struct msghdr* msg, int flags,
00172 Notifier* intr = 0, const char* log = 0);
00174
00177 static int poll_single(int fd, short events, short* revents,
00178 int timeout_ms,
00179 Notifier* intr = 0, const char* log = 0);
00180
00183 static int poll_multiple(struct pollfd* fds, int nfds, int timeout_ms,
00184 Notifier* intr = 0, const char* log = 0);
00185
00189
00191 static int get_nonblocking(int fd, bool *nonblocking,
00192 const char* log = NULL);
00193 static int set_nonblocking(int fd, bool nonblocking,
00194 const char* log = NULL);
00196
00200 static size_t iovec_size(struct iovec* iov, int num) {
00201 size_t size = 0;
00202 for (int i=0; i<num; ++i) {
00203 size += iov[i].iov_len;
00204 }
00205 return size;
00206 }
00207
00208
00210 static int poll_with_notifier(Notifier* intr,
00211 struct pollfd* fds,
00212 size_t nfds,
00213 int timeout,
00214 const struct timeval* start_time,
00215 const char* log);
00216
00218 union RwDataExtraArgs {
00219 const struct msghdr* msg_hdr;
00220
00221 struct {
00222 const struct sockaddr* to;
00223 socklen_t tolen;
00224 } sendto;
00225
00226 struct {
00227 struct sockaddr* from;
00228 socklen_t* fromlen;
00229 } recvfrom;
00230 };
00231
00234 static int rwdata(IO_Op_t op,
00235 int fd,
00236 const struct iovec* iov,
00237 int iovcnt,
00238 int flags,
00239 int timeout,
00240 RwDataExtraArgs* args,
00241 const struct timeval* start_time,
00242 Notifier* intr,
00243 bool ignore_eagain,
00244 const char* log);
00245
00247 static int rwvall(IO_Op_t op,
00248 int fd,
00249 const struct iovec* iov,
00250 int iovcnt,
00251 int timeout,
00252 const struct timeval* start,
00253 Notifier* intr,
00254 const char* fcn_name,
00255 const char* log);
00256
00258 static int adjust_timeout(int timeout, const struct timeval* start);
00259 };
00260
00262 class IOMonitor {
00263 public:
00264 struct info_t {
00265 int timeout_ms_;
00266 int err_code_;
00267
00268 };
00269
00270 virtual ~IOMonitor() {}
00271 virtual void monitor(IO::IO_Op_t op, const info_t* info) = 0;
00272 };
00273
00278 class IOHandlerBase {
00279 public:
00280 IOHandlerBase(Notifier* intr = 0)
00281 : intr_(intr), monitor_(0) {}
00282 ~IOHandlerBase() { delete_z(intr_); }
00283
00284 Notifier* get_notifier() {
00285 return intr_;
00286 }
00287
00288 void interrupt_from_io() {
00289 ASSERT(intr_ != 0);
00290 intr_->notify();
00291 }
00292
00293 void set_notifier(Notifier* intr) {
00294 ASSERT(intr_ == 0);
00295 intr_ = intr;
00296 }
00297
00298 void set_monitor(IOMonitor* monitor) {
00299 monitor_ = monitor;
00300 }
00301
00302 void monitor(IO::IO_Op_t op,
00303 const IOMonitor::info_t* info)
00304 {
00305 if (monitor_ != 0) {
00306 monitor_->monitor(op, info);
00307 }
00308 }
00309
00310 private:
00311 Notifier* intr_;
00312 IOMonitor* monitor_;
00313 };
00314
00315 }
00316
00317 #endif
00318