[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r5226 - in GNUnet/src: transports util/win
From: |
gnunet |
Subject: |
[GNUnet-SVN] r5226 - in GNUnet/src: transports util/win |
Date: |
Mon, 2 Jul 2007 15:42:26 -0600 (MDT) |
Author: durner
Date: 2007-07-02 15:42:25 -0600 (Mon, 02 Jul 2007)
New Revision: 5226
Modified:
GNUnet/src/transports/udp.c
GNUnet/src/util/win/win.cc
Log:
UDP socks block on Win32 for some reason. Use overlapping I/O instead.
Modified: GNUnet/src/transports/udp.c
===================================================================
--- GNUnet/src/transports/udp.c 2007-07-02 17:53:38 UTC (rev 5225)
+++ GNUnet/src/transports/udp.c 2007-07-02 21:42:25 UTC (rev 5226)
@@ -365,13 +365,19 @@
PRIP(ntohl(*(int*)&sin.sin_addr)),
ntohs(sin.sin_port));
#endif
+#ifndef MINGW
if (YES == socket_send_to(udp_sock,
NC_Nonblocking,
mp,
ssize,
&sent,
(const char *) &sin,
- sizeof(sin))) {
+ sizeof(sin)))
+#else
+ sent = win_ols_sendto(udp_sock, mp, ssize, (const char *) &sin, sizeof(sin));
+ if (sent != SOCKET_ERROR)
+#endif
+ {
ok = OK;
if (stats != NULL)
stats->change(stat_bytesSent,
@@ -425,7 +431,11 @@
if (selector == NULL)
return SYSERR;
}
+#ifndef MINGW
sock = SOCKET(PF_INET, SOCK_DGRAM, 17);
+#else
+ sock = win_ols_socket(PF_INET, SOCK_DGRAM, 17);
+#endif
if (sock == -1) {
GE_LOG_STRERROR(ectx,
GE_ERROR | GE_ADMIN | GE_BULK,
Modified: GNUnet/src/util/win/win.cc
===================================================================
--- GNUnet/src/util/win/win.cc 2007-07-02 17:53:38 UTC (rev 5225)
+++ GNUnet/src/util/win/win.cc 2007-07-02 21:42:25 UTC (rev 5226)
@@ -29,7 +29,10 @@
#include "winproc.h"
#include "gnunet_util.h"
+#include "../network/network.h"
+#include <list>
+using namespace std;
#include <ntdef.h>
#ifndef INHERITED_ACE
@@ -38,8 +41,21 @@
extern "C" {
+typedef list<WSAOVERLAPPED *> TOLList;
+
+static HANDLE hOLLock;
+static TOLList lstOL;
+
int plibc_conv_to_win_path(const char *pszUnix, char *pszWindows);
+void __attribute__ ((constructor)) gnunet_win_init() {
+ hOLLock = CreateMutex(NULL, FALSE, NULL);
+}
+
+void __attribute__ ((destructor)) gnunet_win_fini() {
+ CloseHandle(hOLLock);
+}
+
/**
* Enumerate all network adapters
*/
@@ -802,6 +818,78 @@
return ret;
}
+SOCKET win_ols_socket(int af, int type, int protocol)
+{
+ SOCKET s;
+
+ s = WSASocket(af, type, protocol, NULL, 0, WSA_FLAG_OVERLAPPED);
+ SetErrnoFromWinsockError(WSAGetLastError());
+
+ return s;
+}
+
+int win_ols_sendto(struct SocketHandle *s, const char *buf, int len,
+ const struct sockaddr *to, int tolen)
+{
+ int iRet;
+ WSABUF wbuf;
+ WSAOVERLAPPED *ol;
+ DWORD err;
+ DWORD lockRes;
+ unsigned int pending;
+
+ wbuf.buf = (char *) buf;
+ wbuf.len = len;
+ ol = (WSAOVERLAPPED *) MALLOC(sizeof(WSAOVERLAPPED));
+ memset(ol, 0, sizeof(WSAOVERLAPPED));
+ ol->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
+
+ pending = 0;
+
+ iRet = WSASendTo(s->handle, &wbuf, 1, NULL, 0, to, tolen, ol, NULL);
+ err = WSAGetLastError();
+ if (iRet == SOCKET_ERROR) {
+ if (err == WSA_IO_PENDING) {
+ iRet = len;
+ lockRes = WaitForSingleObject(hOLLock, INFINITE);
+ if (lockRes == WAIT_OBJECT_0) {
+ lstOL.push_back(ol);
+ pending = lstOL.size();
+ ReleaseMutex(hOLLock);
+ }
+ }
+ }
+ else if (iRet == 0) {
+ iRet = len;
+ }
+
+ // Try to cleanup
+ lockRes = WaitForSingleObject(hOLLock, pending > 25 ? INFINITE : 0);
+ if (lockRes == WAIT_OBJECT_0) {
+ DWORD sign;
+ TOLList::iterator it;
+ for (it = lstOL.begin(); it != lstOL.end(); it++) {
+ sign = WaitForSingleObject((*it)->hEvent, 0);
+ if (sign == WSA_WAIT_EVENT_0) {
+ TOLList::iterator next;
+
+ ol = *it;
+ CloseHandle(ol->hEvent);
+ FREE(ol);
+ next = it;
+ next++;
+ lstOL.erase(it);
+ if (next == lstOL.end())
+ next--;
+ it = next;
+ }
+ }
+ ReleaseMutex(hOLLock);
+ }
+
+ return iRet;
+}
+
} /* extern "C" */
#endif
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r5226 - in GNUnet/src: transports util/win,
gnunet <=