00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028 #ifndef _terimber_aiocomport_h_
00029 #define _terimber_aiocomport_h_
00030
00031 #include "base/map.h"
00032 #include "base/list.h"
00033 #include "base/stack.h"
00034 #include "base/primitives.h"
00035 #include "threadpool/threadpool.h"
00036
00037 #if OS_TYPE != OS_WIN32
00038
00040 #ifndef HANDLE
00041 typedef int HANDLE;
00042 #endif
00043
00044 #ifndef SOCKET
00045 typedef int SOCKET;
00046 #endif
00047
00049 #ifndef INVALID_SOCKET
00050 #define INVALID_SOCKET ((SOCKET)~0)
00051 #endif
00052
00053
00054 BEGIN_TERIMBER_NAMESPACE
00055 #pragma pack(4)
00056
00057
00061 typedef struct _OVERLAPPED
00062 {
00063 SOCKET hAccept;
00064 sockaddr_in remoteAddress;
00065 unsigned long offset;
00066 } OVERLAPPED;
00067
00070 typedef OVERLAPPED* LPOVERLAPPED;
00071
00074 enum en_type
00075 {
00076 TYPE_UNKNOWN = 0,
00077 TYPE_TCP,
00078 TYPE_UDP,
00079 TYPE_FILE
00080 };
00081
00084
00087 HANDLE
00088 CreateIoCompletionPort
00089 (
00090 HANDLE sock_fd,
00091 HANDLE port_fd,
00092 size_t completion_key,
00093 en_type type
00094 );
00095
00097 bool
00098 AcceptEx
00099 (
00100 HANDLE sock_listen,
00101 LPOVERLAPPED overlapped
00102 );
00103
00105 bool
00106 ConnectEx
00107 (
00108 HANDLE sock_fd,
00109 const struct sockaddr_in* name,
00110 LPOVERLAPPED overlapped
00111 );
00112
00115 bool
00116 WSARecv
00117 (
00118 HANDLE sock_fd,
00119 void* buf,
00120 size_t len,
00121 LPOVERLAPPED overlapped
00122 );
00123
00126 bool
00127 WSARecvFrom
00128 (
00129 HANDLE sock_fd,
00130 void* buf,
00131 size_t len,
00132 struct sockaddr_in* name,
00133 LPOVERLAPPED overlapped
00134 );
00135
00138 bool
00139 ReadFile
00140 (
00141 HANDLE sock_fd,
00142 void* buf,
00143 size_t len,
00144 LPOVERLAPPED overlapped
00145 );
00146
00149 bool
00150 WSASend
00151 (
00152 HANDLE sock_fd,
00153 const void* buf,
00154 size_t len,
00155 LPOVERLAPPED overlapped
00156 );
00157
00160 bool
00161 WSASendTo
00162 (
00163 HANDLE sock_fd,
00164 const void* buf,
00165 size_t len,
00166 const struct sockaddr_in* name,
00167 LPOVERLAPPED overlapped
00168 );
00169
00172 bool
00173 WriteFile
00174 (
00175 HANDLE sock_fd,
00176 const void* buf,
00177 size_t len,
00178 LPOVERLAPPED overlapped
00179 );
00180
00183 int
00184 GetQueuedCompletionStatus
00185 (
00186 HANDLE port_fd,
00187 size_t* number_bytes,
00188 size_t* completion_key,
00189 LPOVERLAPPED* overlapped,
00190 size_t timeout_milliseconds
00191 );
00192
00195 bool
00196 PostQueuedCompletionStatus
00197 (
00198 HANDLE port_fd,
00199 size_t bytes_transferred,
00200 size_t completion_key,
00201 LPOVERLAPPED overlapped
00202 );
00203
00206 bool
00207 CloseHandle
00208 (
00209 HANDLE port_fd
00210 );
00211
00214 bool
00215 CancelIo
00216 (
00217 HANDLE sock_fd,
00218 LPOVERLAPPED overlapped
00219 );
00220
00222 void
00223 SetLog
00224 (
00225 terimber_log* log
00226 );
00227
00229 void
00230 DoXRay
00231 (
00232 );
00233
00235
00239
00240 class aiocomport : public terimber_thread_employer,
00241 public terimber_log_helper
00242 {
00243 public:
00244
00247 enum en_action
00248 {
00249 ACTION_UNKNOWN = 0,
00250 ACTION_USERDATA,
00251 ACTION_CONNECT,
00252 ACTION_ACCEPT,
00253 ACTION_RECV,
00254 ACTION_SEND,
00255 ACTION_READ,
00256 ACTION_WRITE
00257 };
00258 private:
00261 class queue_item : public aiocb
00262 {
00263 public:
00265 queue_item()
00266 {
00267 memset(this, 0, sizeof(queue_item));
00268 aio_fildes = (int)INVALID_SOCKET;
00269 }
00270
00271 en_action _action;
00272 size_t _error;
00273 size_t _processed;
00274 size_t _key;
00275 LPOVERLAPPED _overlapped;
00276 };
00277
00280 typedef node_allocator< _list< queue_item >::_node > queue_allocator_t;
00283 typedef _list< queue_item, queue_allocator_t > queue_container_t;
00286 typedef queue_container_t::iterator queue_container_iterator_t;
00287
00290 class port_attributes
00291 {
00293 port_attributes& operator=(const port_attributes& x);
00294 public:
00296 port_attributes() : _go_to_exit(false), _loop_lock(false)
00297 {
00298 }
00299
00301 port_attributes(const port_attributes& x) : _go_to_exit(x._go_to_exit), _loop_lock(x._loop_lock)
00302 {
00303 }
00304
00305 bool _go_to_exit;
00306 size_t _loop_lock;
00307 event _queue_event;
00308 event _exit_event;
00309 queue_container_t _completion_container;
00310 };
00311
00314 typedef map< HANDLE, port_attributes > port_attr_map_t;
00317 typedef port_attr_map_t::iterator port_attr_map_iterator_t;
00318
00321 class fd_item
00322 {
00323 public:
00325 fd_item(port_attr_map_iterator_t port_iter, size_t completion_key, unsigned long int type) :
00326 _port_iter(port_iter),
00327 _completion_key(completion_key),
00328 _type((en_type)type)
00329 {
00330 }
00331
00332 queue_container_t _initial_container;
00333 port_attr_map_iterator_t _port_iter;
00334 size_t _completion_key;
00335 en_type _type;
00336 };
00337
00340 typedef map< HANDLE, fd_item > fd_port_map_t;
00341
00342
00343 public:
00345 aiocomport();
00347 ~aiocomport();
00348
00351 HANDLE
00352 CreateIoCompletionPort
00353 (
00354 HANDLE sock_fd,
00355 HANDLE port_fd,
00356 size_t completion_key,
00357 en_type type
00358 );
00359
00361 bool
00362 AcceptEx
00363 (
00364 HANDLE sock_listen,
00365 LPOVERLAPPED overlapped
00366 );
00367
00369 bool
00370 ConnectEx
00371 (
00372 HANDLE sock_fd,
00373 const struct sockaddr_in* name,
00374 LPOVERLAPPED overlapped
00375 );
00376
00379 bool
00380 WSARecv
00381 (
00382 HANDLE sock_fd,
00383 void* buf,
00384 size_t len,
00385 LPOVERLAPPED overlapped
00386 );
00387
00390 bool
00391 WSARecvFrom
00392 (
00393 HANDLE sock_fd,
00394 void* buf,
00395 size_t len,
00396 struct sockaddr_in* name,
00397 LPOVERLAPPED overlapped
00398 );
00399
00400
00402 bool
00403 ReadFile
00404 (
00405 HANDLE sock_fd,
00406 void* buf,
00407 size_t len,
00408 LPOVERLAPPED overlapped
00409 );
00410
00413 bool
00414 WSASend
00415 (
00416 HANDLE sock_fd,
00417 const void* buf,
00418 size_t len,
00419 LPOVERLAPPED overlapped
00420 );
00421
00424 bool
00425 WSASendTo
00426 (
00427 HANDLE sock_fd,
00428 const void* buf,
00429 size_t len,
00430 const struct sockaddr_in* name,
00431 LPOVERLAPPED overlapped
00432 );
00433
00435 bool
00436 WriteFile
00437 (
00438 HANDLE sock_fd,
00439 const void* buf,
00440 size_t len,
00441 LPOVERLAPPED overlapped
00442 );
00443
00446 int
00447 GetQueuedCompletionStatus
00448 (
00449 HANDLE port_fd,
00450 size_t* number_bytes,
00451 size_t* completion_key,
00452 LPOVERLAPPED* overlapped,
00453 size_t timeout_milliseconds
00454 );
00455
00458 bool
00459 PostQueuedCompletionStatus
00460 (
00461 HANDLE port_fd,
00462 size_t bytes_transferred,
00463 size_t completion_key,
00464 LPOVERLAPPED overlapped
00465 );
00466
00469 bool
00470 CloseHandle
00471 (
00472 HANDLE port_fd
00473 );
00474
00477 bool
00478 CancelIo
00479 (
00480 HANDLE sock_fd,
00481 LPOVERLAPPED overlapped
00482 );
00483
00485 void
00486 SetLog
00487 (
00488 terimber_log* log
00489 );
00490
00492 void
00493 DoXRay
00494 (
00495 );
00496
00497
00499 void
00500 func_sock_signal(int fd, int si_code);
00501
00503 void
00504 func_file_signal(int fd, void* ptr);
00505
00506 protected:
00509 virtual
00510 bool
00511 v_has_job( size_t ident,
00512 void* data
00513 );
00516 virtual
00517 void
00518 v_do_job( size_t ident,
00519 void* data
00520 );
00521
00522 private:
00524 bool
00525 initiate_action( en_action action,
00526 HANDLE sock_id,
00527 LPOVERLAPPED overlapped,
00528 const void* buf,
00529 size_t len,
00530 const sockaddr_in* name
00531 );
00532 private:
00533 mutex _port_mtx;
00534 port_attr_map_t _port_attr_map;
00535 fd_port_map_t _fd_port_map;
00536
00537 unique_key_generator _generator;
00538 size_t _capacity;
00539
00540 queue_allocator_t _queue_allocator;
00541
00542 thread _event_thread;
00543 volatile pthread_t _event_thread_id;
00544 event _ev_activate;
00545 event _ev_deactivate;
00546 #ifdef NO_NPTL
00547 event _ev_wakeup;
00548 #endif
00549 };
00550
00551 #pragma pack()
00552 END_TERIMBER_NAMESPACE
00553
00554 #endif
00555
00556 #endif // _terimber_completionport_h_
00557