gnunet-svn
[Top][All Lists]
Advanced

[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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]