FSocket_Win32.cxx 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930
  1. // FSocket was adapted from K.A. Knizhnik's very nice SAL library.
  2. #include <assert.h>
  3. #include <string.h>
  4. #include <stdio.h>
  5. #include <stddef.h>
  6. #include <stdlib.h>
  7. #include "FSocket_Win32.H"
  8. #define MAX_HOST_NAME 256
  9. #define MILLISECOND 1000
  10. static HANDLE WatchDogMutex;
  11. class win_socket_library {
  12. public:
  13. win_socket_library() {
  14. WSADATA wsa;
  15. if (WSAStartup(MAKEWORD(1, 1), &wsa) != 0) {
  16. fprintf(stderr,"Failed to initialize windows sockets: %d\n",
  17. WSAGetLastError());
  18. }
  19. //
  20. // This mutex is used to recognize process termination
  21. //
  22. WatchDogMutex = CreateMutex(NULL, TRUE, NULL);
  23. }
  24. ~win_socket_library() {
  25. WSACleanup();
  26. }
  27. };
  28. static win_socket_library ws32_lib;
  29. int FSocket_Win32::open(int listen_queue_size)
  30. {
  31. unsigned short port;
  32. char* p;
  33. assert(address != NULL);
  34. if ((p = strchr(address, ':')) == NULL
  35. || sscanf(p+1, "%hd", &port) != 1)
  36. {
  37. errcode = bad_address;
  38. return 0;
  39. }
  40. if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  41. errcode = WSAGetLastError();
  42. return 0;
  43. }
  44. struct sockaddr_in insock;
  45. insock.sin_family = AF_INET;
  46. insock.sin_addr.s_addr = htonl(INADDR_ANY);
  47. insock.sin_port = htons(port);
  48. if (bind(s, (sockaddr*)&insock, sizeof(insock)) != 0) {
  49. errcode = WSAGetLastError();
  50. closesocket(s);
  51. return 0;
  52. }
  53. if (listen(s, listen_queue_size) != 0) {
  54. errcode = WSAGetLastError();
  55. closesocket(s);
  56. return 0;
  57. }
  58. errcode = ok;
  59. state = ss_open;
  60. return 1;
  61. }
  62. int FSocket_Win32::valid()
  63. {
  64. return errcode == ok;
  65. }
  66. void FSocket_Win32::get_error_text(char* buf, size_t buf_size)
  67. {
  68. int len;
  69. char* msg;
  70. char msgbuf[64];
  71. switch(errcode) {
  72. case ok:
  73. msg = "ok";
  74. break;
  75. case not_opened:
  76. msg = "socket not opened";
  77. break;
  78. case bad_address:
  79. msg = "bad address";
  80. break;
  81. case connection_failed:
  82. msg = "exceed limit of attempts of connection to server";
  83. break;
  84. case broken_pipe:
  85. msg = "connection is broken";
  86. break;
  87. case invalid_access_mode:
  88. msg = "invalid access mode";
  89. break;
  90. default:
  91. len = FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  92. NULL,
  93. errcode,
  94. 0,
  95. buf,
  96. buf_size,
  97. NULL);
  98. if (len == 0) {
  99. sprintf(msgbuf, "unknown error code %u", errcode);
  100. msg = msgbuf;
  101. }
  102. }
  103. strncpy(buf, msg, buf_size);
  104. }
  105. FSocket* FSocket_Win32::accept()
  106. {
  107. if (state != ss_open) {
  108. errcode = not_opened;
  109. return NULL;
  110. }
  111. SOCKET new_sock = ::accept(s, NULL, NULL );
  112. if (new_sock == INVALID_SOCKET) {
  113. errcode = WSAGetLastError();
  114. return NULL;
  115. } else {
  116. static struct linger l = {1, LINGER_TIME};
  117. if (setsockopt(s, SOL_SOCKET, SO_LINGER, (char*)&l, sizeof l) != 0) {
  118. errcode = invalid_access_mode;
  119. closesocket(s);
  120. return NULL;
  121. }
  122. int enabled = 1;
  123. if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&enabled,
  124. sizeof enabled) != 0)
  125. {
  126. errcode = WSAGetLastError();
  127. closesocket(s);
  128. return NULL;
  129. }
  130. errcode = ok;
  131. return new FSocket_Win32(new_sock);
  132. }
  133. }
  134. int FSocket_Win32::cancel_accept()
  135. {
  136. int result = close();
  137. // Wakeup listener
  138. delete FSocket::connect(address, sock_global_domain, 1, 0);
  139. return result;
  140. }
  141. int FSocket_Win32::connect(int max_attempts, time_t timeout)
  142. {
  143. char hostname[MAX_HOST_NAME];
  144. char *p;
  145. unsigned short port;
  146. assert(address != NULL);
  147. if ((p = strchr(address, ':')) == NULL
  148. || p - address >= sizeof(hostname)
  149. || sscanf(p+1, "%hd", &port) != 1)
  150. {
  151. errcode = bad_address;
  152. return 0;
  153. }
  154. memcpy(hostname, address, p - address);
  155. hostname[p - address] = '\0';
  156. struct sockaddr_in insock; // inet socket address
  157. struct hostent* hp; // entry in hosts table
  158. if ((hp = gethostbyname(hostname)) == NULL || hp->h_addrtype != AF_INET) {
  159. errcode = bad_address;
  160. return 0;
  161. }
  162. insock.sin_family = AF_INET;
  163. insock.sin_port = htons(port);
  164. memcpy(&insock.sin_addr, hp->h_addr, sizeof insock.sin_addr);
  165. while (1) {
  166. if ((s = socket(AF_INET, SOCK_STREAM, 0)) == INVALID_SOCKET) {
  167. errcode = WSAGetLastError();
  168. return 0;
  169. }
  170. if (::connect(s, (sockaddr*)&insock, sizeof insock) != 0) {
  171. errcode = WSAGetLastError();
  172. closesocket(s);
  173. if (errcode == WSAECONNREFUSED) {
  174. if (--max_attempts > 0) {
  175. Sleep(timeout*MILLISECOND);
  176. } else {
  177. break;
  178. }
  179. } else {
  180. return 0;
  181. }
  182. } else {
  183. int enabled = 1;
  184. if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (char*)&enabled,
  185. sizeof enabled) != 0)
  186. {
  187. errcode = WSAGetLastError();
  188. closesocket(s);
  189. return 0;
  190. }
  191. errcode = ok;
  192. state = ss_open;
  193. return 1;
  194. }
  195. }
  196. errcode = connection_failed;
  197. return 0;
  198. }
  199. int FSocket_Win32::read(void* buf, size_t min_size, size_t max_size,
  200. time_t timeout)
  201. {
  202. size_t size = 0;
  203. time_t start = 0;
  204. if (state != ss_open) {
  205. errcode = not_opened;
  206. return -1;
  207. }
  208. if (timeout != WAIT_FOREVER) {
  209. start = time(NULL);
  210. }
  211. do {
  212. int rc;
  213. if (timeout != WAIT_FOREVER) {
  214. fd_set events;
  215. struct timeval tm;
  216. FD_ZERO(&events);
  217. FD_SET(s, &events);
  218. tm.tv_sec = timeout;
  219. tm.tv_usec = 0;
  220. rc = select(s+1, &events, NULL, NULL, &tm);
  221. if (rc < 0) {
  222. errcode = errno;
  223. return -1;
  224. }
  225. if (rc == 0) {
  226. return size;
  227. }
  228. time_t now = time(NULL);
  229. timeout = start + timeout >= now ? 0 : timeout + start - now;
  230. }
  231. rc = recv(s, (char*)buf + size, max_size - size, 0);
  232. if (rc < 0) {
  233. errcode = WSAGetLastError();
  234. return -1;
  235. } else if (rc == 0) {
  236. errcode = broken_pipe;
  237. return -1;
  238. } else {
  239. size += rc;
  240. }
  241. } while (size < min_size);
  242. return (int)size;
  243. }
  244. int FSocket_Win32::read(void* buf, size_t size)
  245. {
  246. if (state != ss_open) {
  247. errcode = not_opened;
  248. return 0;
  249. }
  250. do {
  251. int rc = recv(s, (char*)buf, size, 0);
  252. if (rc < 0) {
  253. errcode = WSAGetLastError();
  254. return 0;
  255. } else if (rc == 0) {
  256. errcode = broken_pipe;
  257. return 0;
  258. } else {
  259. buf = (char*)buf + rc;
  260. size -= rc;
  261. }
  262. } while (size != 0);
  263. return 1;
  264. }
  265. int FSocket_Win32::write(void const* buf, size_t size)
  266. {
  267. if (state != ss_open) {
  268. errcode = not_opened;
  269. return 0;
  270. }
  271. do {
  272. int rc = send(s, (char*)buf, size, 0);
  273. if (rc < 0) {
  274. errcode = WSAGetLastError();
  275. return 0;
  276. } else if (rc == 0) {
  277. errcode = broken_pipe;
  278. return 0;
  279. } else {
  280. buf = (char*)buf + rc;
  281. size -= rc;
  282. }
  283. } while (size != 0);
  284. return 1;
  285. }
  286. int FSocket_Win32::shutdown()
  287. {
  288. if (state == ss_open) {
  289. state = ss_shutdown;
  290. int rc = ::shutdown(s, 2);
  291. if (rc != 0) {
  292. errcode = WSAGetLastError();
  293. return 0;
  294. }
  295. }
  296. errcode = ok;
  297. return 1;
  298. }
  299. int FSocket_Win32::close()
  300. {
  301. if (state != ss_close) {
  302. state = ss_close;
  303. if (closesocket(s) == 0) {
  304. errcode = ok;
  305. return 1;
  306. } else {
  307. errcode = WSAGetLastError();
  308. return 0;
  309. }
  310. }
  311. return 1;
  312. }
  313. FSocket_Win32::~FSocket_Win32()
  314. {
  315. close();
  316. }
  317. FSocket_Win32::FSocket_Win32(const char* addr)
  318. {
  319. address = strdup(addr);
  320. errcode = ok;
  321. s = INVALID_SOCKET;
  322. }
  323. FSocket_Win32::FSocket_Win32(SOCKET new_sock)
  324. {
  325. s = new_sock;
  326. address = NULL;
  327. state = ss_open;
  328. errcode = ok;
  329. }
  330. FSocket* FSocket::create_local(char const* address, int listen_queue_size)
  331. {
  332. FSocket_Win32_Local* sock = new FSocket_Win32_Local(address);
  333. sock->open(listen_queue_size);
  334. return sock;
  335. }
  336. FSocket* FSocket::create_global(char const* address, int listen_queue_size)
  337. {
  338. FSocket_Win32* sock = new FSocket_Win32(address);
  339. sock->open(listen_queue_size);
  340. return sock;
  341. }
  342. FSocket* FSocket::connect(char const* address,
  343. socket_domain domain,
  344. int max_attempts,
  345. time_t timeout)
  346. {
  347. size_t hostname_len;
  348. char* port;
  349. if (domain == sock_local_domain
  350. || (domain == sock_any_domain
  351. && ((port = strchr(address, ':')) == NULL
  352. || ((hostname_len = port - address) == 9
  353. && strncmp(address, "localhost", hostname_len) == 0))))
  354. {
  355. FSocket_Win32_Local* s = new FSocket_Win32_Local(address);
  356. s->connect(max_attempts, timeout);
  357. return s;
  358. } else {
  359. FSocket_Win32* s = new FSocket_Win32(address);
  360. s->connect(max_attempts, timeout);
  361. return s;
  362. }
  363. }
  364. char const* get_process_name()
  365. {
  366. static char name[MAX_HOST_NAME+8];
  367. gethostname(name, MAX_HOST_NAME);
  368. sprintf(name + strlen(name), ":%x", GetCurrentProcessId());
  369. return name;
  370. }
  371. //
  372. // Local windows sockets
  373. //
  374. int FSocket_Win32_Local::read(void* buf, size_t min_size, size_t max_size,
  375. time_t timeout)
  376. {
  377. time_t start = 0;
  378. char* dst = (char*)buf;
  379. size_t size = 0;
  380. Error = ok;
  381. if (timeout != WAIT_FOREVER) {
  382. start = time(NULL);
  383. timeout *= 1000; // convert seconds to miliseconds
  384. }
  385. while (size < min_size && state == ss_open) {
  386. RcvBuf->RcvWaitFlag = 1;
  387. size_t begin = RcvBuf->DataBeg;
  388. size_t end = RcvBuf->DataEnd;
  389. size_t rcv_size = (begin <= end)
  390. ? end - begin : sizeof(RcvBuf->Data) - begin;
  391. if (rcv_size > 0) {
  392. RcvBuf->RcvWaitFlag = 0;
  393. if (rcv_size >= max_size) {
  394. memcpy(dst, &RcvBuf->Data[begin], max_size);
  395. begin += max_size;
  396. size += max_size;
  397. } else {
  398. memcpy(dst, &RcvBuf->Data[begin], rcv_size);
  399. begin += rcv_size;
  400. dst += rcv_size;
  401. size += rcv_size;
  402. }
  403. RcvBuf->DataBeg = (begin == sizeof(RcvBuf->Data)) ? 0 : begin;
  404. if (RcvBuf->SndWaitFlag) {
  405. SetEvent(Signal[RTR]);
  406. }
  407. } else {
  408. HANDLE h[2];
  409. h[0] = Signal[RD];
  410. h[1] = Mutex;
  411. int rc = WaitForMultipleObjects(2, h, false, timeout);
  412. RcvBuf->RcvWaitFlag = false;
  413. if (rc != WAIT_OBJECT_0) {
  414. if (rc == WAIT_OBJECT_0+1 || rc == WAIT_ABANDONED+1) {
  415. Error = broken_pipe;
  416. ReleaseMutex(Mutex);
  417. } else if (rc == WAIT_TIMEOUT) {
  418. return size;
  419. } else {
  420. Error = GetLastError();
  421. }
  422. return -1;
  423. }
  424. if (timeout != WAIT_FOREVER) {
  425. time_t now = time(NULL);
  426. timeout = timeout >= (now - start)*1000
  427. ? 0 : timeout - (now - start)*1000;
  428. }
  429. }
  430. }
  431. return size < min_size ? -1 : (int)size;
  432. }
  433. int FSocket_Win32_Local::read(void* buf, size_t size)
  434. {
  435. char* dst = (char*)buf;
  436. Error = ok;
  437. while (size > 0 && state == ss_open) {
  438. RcvBuf->RcvWaitFlag = 1;
  439. size_t begin = RcvBuf->DataBeg;
  440. size_t end = RcvBuf->DataEnd;
  441. size_t rcv_size = (begin <= end)
  442. ? end - begin : sizeof(RcvBuf->Data) - begin;
  443. if (rcv_size > 0) {
  444. RcvBuf->RcvWaitFlag = 0;
  445. if (rcv_size >= size) {
  446. memcpy(dst, &RcvBuf->Data[begin], size);
  447. begin += size;
  448. size = 0;
  449. } else {
  450. memcpy(dst, &RcvBuf->Data[begin], rcv_size);
  451. begin += rcv_size;
  452. dst += rcv_size;
  453. size -= rcv_size;
  454. }
  455. RcvBuf->DataBeg = (begin == sizeof(RcvBuf->Data)) ? 0 : begin;
  456. if (RcvBuf->SndWaitFlag) {
  457. SetEvent(Signal[RTR]);
  458. }
  459. } else {
  460. HANDLE h[2];
  461. h[0] = Signal[RD];
  462. h[1] = Mutex;
  463. int rc = WaitForMultipleObjects(2, h, FALSE, INFINITE);
  464. RcvBuf->RcvWaitFlag = 0;
  465. if (rc != WAIT_OBJECT_0) {
  466. if (rc == WAIT_OBJECT_0+1 || rc == WAIT_ABANDONED+1) {
  467. Error = broken_pipe;
  468. ReleaseMutex(Mutex);
  469. } else {
  470. Error = GetLastError();
  471. }
  472. return 0;
  473. }
  474. }
  475. }
  476. return size == 0;
  477. }
  478. int FSocket_Win32_Local::write(const void* buf, size_t size)
  479. {
  480. char* src = (char*)buf;
  481. Error = ok;
  482. while (size > 0 && state == ss_open) {
  483. SndBuf->SndWaitFlag = 1;
  484. size_t begin = SndBuf->DataBeg;
  485. size_t end = SndBuf->DataEnd;
  486. size_t snd_size = (begin <= end)
  487. ? sizeof(SndBuf->Data) - end - (begin == 0)
  488. : begin - end - 1;
  489. if (snd_size > 0) {
  490. SndBuf->SndWaitFlag = 0;
  491. if (snd_size >= size) {
  492. memcpy(&SndBuf->Data[end], src, size);
  493. end += size;
  494. size = 0;
  495. } else {
  496. memcpy(&SndBuf->Data[end], src, snd_size);
  497. end += snd_size;
  498. src += snd_size;
  499. size -= snd_size;
  500. }
  501. SndBuf->DataEnd = (end == sizeof(SndBuf->Data)) ? 0 : end;
  502. if (SndBuf->RcvWaitFlag) {
  503. SetEvent(Signal[TD]);
  504. }
  505. } else {
  506. HANDLE h[2];
  507. h[0] = Signal[RTT];
  508. h[1] = Mutex;
  509. int rc = WaitForMultipleObjects(2, h, FALSE, INFINITE);
  510. RcvBuf->SndWaitFlag = 0;
  511. if (rc != WAIT_OBJECT_0) {
  512. if (rc == WAIT_OBJECT_0+1 || rc == WAIT_ABANDONED+1) {
  513. Error = broken_pipe;
  514. ReleaseMutex(Mutex);
  515. } else {
  516. Error = GetLastError();
  517. }
  518. return 0;
  519. }
  520. }
  521. }
  522. return size == 0;
  523. }
  524. #define MAX_ADDRESS_LEN 64
  525. FSocket_Win32_Local::FSocket_Win32_Local(const char* address)
  526. {
  527. Name = strdup(address);
  528. Error = not_opened;
  529. Mutex = NULL;
  530. }
  531. int FSocket_Win32_Local::open(int)
  532. {
  533. char buf[MAX_ADDRESS_LEN];
  534. int i;
  535. for (i = RD; i <= RTT; i++) {
  536. sprintf(buf, "%s.%c", Name, i + '0');
  537. Signal[i] = CreateEvent(NULL, 0, 0, buf);
  538. if (GetLastError() == ERROR_ALREADY_EXISTS) {
  539. WaitForSingleObject(Signal[i], 0);
  540. }
  541. if (!Signal[i]) {
  542. Error = GetLastError();
  543. while (--i >= 0) {
  544. CloseHandle(Signal[i]);
  545. }
  546. return 0;
  547. }
  548. }
  549. sprintf(buf, "%s.shr", Name);
  550. BufHnd = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
  551. 0, sizeof(socket_buf)*2, buf);
  552. if (!BufHnd) {
  553. Error = GetLastError();
  554. for (i = RD; i <= RTT; i++) {
  555. CloseHandle(Signal[i]);
  556. }
  557. return 0;
  558. }
  559. RcvBuf = (socket_buf*)MapViewOfFile(BufHnd, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  560. if (!RcvBuf) {
  561. Error = GetLastError();
  562. CloseHandle(BufHnd);
  563. for (i = RD; i <= RTT; i++) {
  564. CloseHandle(Signal[i]);
  565. }
  566. return 0;
  567. }
  568. SndBuf = RcvBuf+1;
  569. RcvBuf->DataBeg = RcvBuf->DataEnd = 0;
  570. SndBuf->DataBeg = SndBuf->DataEnd = 0;
  571. Error = ok;
  572. state = ss_open;
  573. return 1;
  574. }
  575. FSocket_Win32_Local::FSocket_Win32_Local()
  576. {
  577. int i;
  578. BufHnd = NULL;
  579. Mutex = NULL;
  580. Name = NULL;
  581. for (i = RD; i <= RTT; i++) {
  582. Signal[i] = CreateEvent(NULL, 0, 0, NULL);
  583. if (!Signal[i]) {
  584. Error = GetLastError();
  585. while (--i >= 0) {
  586. CloseHandle(Signal[i]);
  587. }
  588. return;
  589. }
  590. }
  591. // create anonymous shared memory section
  592. BufHnd = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
  593. 0, sizeof(socket_buf)*2, NULL);
  594. if (!BufHnd) {
  595. Error = GetLastError();
  596. for (i = RD; i <= RTT; i++) {
  597. CloseHandle(Signal[i]);
  598. }
  599. return;
  600. }
  601. RcvBuf = (socket_buf*)MapViewOfFile(BufHnd, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  602. if (!RcvBuf) {
  603. Error = GetLastError();
  604. CloseHandle(BufHnd);
  605. for (i = RD; i <= RTT; i++) {
  606. CloseHandle(Signal[i]);
  607. }
  608. BufHnd = NULL;
  609. return;
  610. }
  611. SndBuf = RcvBuf+1;
  612. RcvBuf->DataBeg = RcvBuf->DataEnd = 0;
  613. SndBuf->DataBeg = SndBuf->DataEnd = 0;
  614. Error = ok;
  615. state = ss_open;
  616. }
  617. FSocket_Win32_Local::~FSocket_Win32_Local()
  618. {
  619. close();
  620. delete[] Name;
  621. }
  622. FSocket* FSocket_Win32_Local::accept()
  623. {
  624. HANDLE h[2];
  625. if (state != ss_open) {
  626. return NULL;
  627. }
  628. connect_data* cdp = (connect_data*)SndBuf->Data;
  629. cdp->Pid = GetCurrentProcessId();
  630. cdp->Mutex = WatchDogMutex;
  631. while (1) {
  632. SetEvent(Signal[RTR]);
  633. int rc = WaitForSingleObject(Signal[RD], ACCEPT_TIMEOUT);
  634. if (rc == WAIT_OBJECT_0) {
  635. if (state != ss_open) {
  636. Error = not_opened;
  637. return NULL;
  638. }
  639. Error = ok;
  640. break;
  641. } else if (rc != WAIT_TIMEOUT) {
  642. Error = GetLastError();
  643. return NULL;
  644. }
  645. }
  646. FSocket_Win32_Local* sock = new FSocket_Win32_Local();
  647. sock->Mutex = ((connect_data*)RcvBuf->Data)->Mutex;
  648. accept_data* adp = (accept_data*)SndBuf->Data;
  649. adp->BufHnd = sock->BufHnd;
  650. for (int i = RD; i <= RTT; i++) {
  651. adp->Signal[(i + TD - RD) & RTT] = sock->Signal[i];
  652. }
  653. SetEvent(Signal[TD]);
  654. h[0] = Signal[RD];
  655. h[1] = sock->Mutex;
  656. int rc = WaitForMultipleObjects(2, h, FALSE, INFINITE);
  657. if (rc != WAIT_OBJECT_0) {
  658. if (rc == WAIT_OBJECT_0+1 || rc == WAIT_ABANDONED+1) {
  659. Error = broken_pipe;
  660. ReleaseMutex(Mutex);
  661. } else {
  662. Error = GetLastError();
  663. }
  664. delete sock;
  665. return NULL;
  666. }
  667. return sock;
  668. }
  669. int FSocket_Win32_Local::cancel_accept()
  670. {
  671. state = ss_shutdown;
  672. SetEvent(Signal[RD]);
  673. SetEvent(Signal[RTT]);
  674. return 1;
  675. }
  676. int FSocket_Win32_Local::valid()
  677. {
  678. return !Error;
  679. }
  680. int FSocket_Win32_Local::close()
  681. {
  682. if (state != ss_close) {
  683. state = ss_close;
  684. if (Mutex) {
  685. CloseHandle(Mutex);
  686. }
  687. for (int i = RD; i <= RTT; i++) {
  688. CloseHandle(Signal[i]);
  689. }
  690. UnmapViewOfFile(RcvBuf < SndBuf ? RcvBuf : SndBuf);
  691. CloseHandle(BufHnd);
  692. Error = not_opened;
  693. }
  694. return 1;
  695. }
  696. void FSocket_Win32_Local::get_error_text(char* buf, size_t buf_size)
  697. {
  698. switch (Error) {
  699. case ok:
  700. strncpy(buf, "ok", buf_size);
  701. break;
  702. case not_opened:
  703. strncpy(buf, "socket not opened", buf_size);
  704. break;
  705. case broken_pipe:
  706. strncpy(buf, "connection is broken", buf_size);
  707. break;
  708. case timeout_expired:
  709. strncpy(buf, "connection timeout expired", buf_size);
  710. break;
  711. default:
  712. FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,
  713. NULL,
  714. Error,
  715. 0,
  716. buf,
  717. buf_size,
  718. NULL);
  719. }
  720. }
  721. int FSocket_Win32_Local::shutdown()
  722. {
  723. if (state == ss_open) {
  724. state = ss_shutdown;
  725. SetEvent(Signal[RD]);
  726. SetEvent(Signal[RTT]);
  727. }
  728. return 1;
  729. }
  730. int FSocket_Win32_Local::connect(int max_attempts, time_t timeout)
  731. {
  732. char buf[MAX_ADDRESS_LEN];
  733. int rc, i, error_code;
  734. HANDLE h[2];
  735. for (i = RD; i <= RTT; i++) {
  736. sprintf(buf, "%s.%c", Name, ((i + TD - RD) & RTT) + '0');
  737. Signal[i] = CreateEvent(NULL, 0, 0, buf);
  738. if (!Signal[i]) {
  739. Error = GetLastError();
  740. while (--i >= 0) {
  741. CloseHandle(Signal[i]);
  742. }
  743. return 0;
  744. }
  745. }
  746. sprintf(buf, "%s.shr", Name);
  747. BufHnd = CreateFileMapping(INVALID_HANDLE_VALUE, NULL, PAGE_READWRITE,
  748. 0, sizeof(socket_buf)*2, buf);
  749. if (!BufHnd) {
  750. Error = GetLastError();
  751. for (i = RD; i <= RTT; i++) {
  752. CloseHandle(Signal[i]);
  753. }
  754. return 0;
  755. }
  756. SndBuf = (socket_buf*)MapViewOfFile(BufHnd, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  757. if (!SndBuf) {
  758. Error = GetLastError();
  759. for (i = RD; i <= RTT; i++) {
  760. CloseHandle(Signal[i]);
  761. }
  762. CloseHandle(BufHnd);
  763. return 0;
  764. }
  765. RcvBuf = SndBuf+1;
  766. state = ss_shutdown;
  767. Mutex = NULL;
  768. rc = WaitForSingleObject(Signal[RTT],timeout*max_attempts*MILLISECOND);
  769. if (rc != WAIT_OBJECT_0) {
  770. error_code = rc == WAIT_TIMEOUT ? timeout_expired : GetLastError();
  771. close();
  772. Error = error_code;
  773. return 0;
  774. }
  775. connect_data* cdp = (connect_data*)RcvBuf->Data;
  776. HANDLE hServer = OpenProcess(STANDARD_RIGHTS_REQUIRED|PROCESS_DUP_HANDLE,
  777. FALSE, cdp->Pid);
  778. if (!hServer) {
  779. error_code = GetLastError();
  780. close();
  781. Error = error_code;
  782. return 0;
  783. }
  784. HANDLE hSelf = GetCurrentProcess();
  785. if (!DuplicateHandle(hServer, cdp->Mutex, hSelf, &Mutex,
  786. 0, FALSE, DUPLICATE_SAME_ACCESS) ||
  787. !DuplicateHandle(hSelf, WatchDogMutex, hServer,
  788. &((connect_data*)SndBuf->Data)->Mutex,
  789. 0, FALSE, DUPLICATE_SAME_ACCESS))
  790. {
  791. error_code = GetLastError();
  792. CloseHandle(hServer);
  793. close();
  794. Error = error_code;
  795. return 0;
  796. }
  797. SetEvent(Signal[TD]);
  798. h[0] = Signal[RD];
  799. h[1] = Mutex;
  800. rc = WaitForMultipleObjects(2, h, FALSE, INFINITE);
  801. if (rc != WAIT_OBJECT_0) {
  802. if (rc == WAIT_OBJECT_0+1 || rc == WAIT_ABANDONED+1) {
  803. error_code = broken_pipe;
  804. ReleaseMutex(Mutex);
  805. } else {
  806. error_code = GetLastError();
  807. }
  808. CloseHandle(hServer);
  809. close();
  810. Error = error_code;
  811. return 0;
  812. }
  813. accept_data ad = *(accept_data*)RcvBuf->Data;
  814. SetEvent(Signal[TD]);
  815. for (i = RD; i <= RTT; i++) {
  816. CloseHandle(Signal[i]);
  817. }
  818. UnmapViewOfFile(SndBuf);
  819. CloseHandle(BufHnd);
  820. BufHnd = NULL;
  821. if (!DuplicateHandle(hServer, ad.BufHnd, hSelf, &BufHnd,
  822. 0, FALSE, DUPLICATE_SAME_ACCESS))
  823. {
  824. Error = GetLastError();
  825. CloseHandle(hServer);
  826. CloseHandle(Mutex);
  827. return 0;
  828. } else {
  829. for (i = RD; i <= RTT; i++) {
  830. if (!DuplicateHandle(hServer, ad.Signal[i],
  831. hSelf, &Signal[i],
  832. 0, FALSE, DUPLICATE_SAME_ACCESS))
  833. {
  834. Error = GetLastError();
  835. CloseHandle(hServer);
  836. CloseHandle(BufHnd);
  837. CloseHandle(Mutex);
  838. while (--i >= 0) CloseHandle(Signal[1]);
  839. return 0;
  840. }
  841. }
  842. }
  843. CloseHandle(hServer);
  844. SndBuf = (socket_buf*)MapViewOfFile(BufHnd, FILE_MAP_ALL_ACCESS, 0, 0, 0);
  845. if (!SndBuf) {
  846. Error = GetLastError();
  847. CloseHandle(BufHnd);
  848. CloseHandle(Mutex);
  849. for (i = RD; i <= RTT; i++) {
  850. CloseHandle(Signal[i]);
  851. }
  852. return 0;
  853. }
  854. RcvBuf = SndBuf+1;
  855. Error = ok;
  856. state = ss_open;
  857. return 1;
  858. }