stream: Call WSAStartup() before calling any winsock functions.
authorGurucharan Shetty <gshetty@nicira.com>
Mon, 17 Mar 2014 16:28:07 +0000 (09:28 -0700)
committerGurucharan Shetty <gshetty@nicira.com>
Tue, 18 Mar 2014 20:18:58 +0000 (13:18 -0700)
The WSAStartup function initiates use of the Winsock DLL by a process.
The function should be called before any winsock related functions
are called.

Since, we use stream-fd-windows through pstream_open or stream_open
add the WSAStartup() call there.

The current version of the Windows Sockets specification is version 2.2

Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
Acked-by: Ben Pfaff <blp@nicira.com>
lib/stream.c

index 1dfecf0..fa5b6d6 100644 (file)
 #include "ofpbuf.h"
 #include "openflow/nicira-ext.h"
 #include "openflow/openflow.h"
+#include "ovs-thread.h"
 #include "packets.h"
 #include "poll-loop.h"
 #include "random.h"
+#include "socket-util.h"
 #include "util.h"
 #include "vlog.h"
 
@@ -69,6 +71,27 @@ static const struct pstream_class *pstream_classes[] = {
 #endif
 };
 
+#ifdef _WIN32
+static void
+do_winsock_start(void)
+{
+    WSADATA wsaData;
+    int error;
+
+    error = WSAStartup(MAKEWORD(2, 2), &wsaData);
+    if (error != 0) {
+        VLOG_FATAL("WSAStartup failed: %s", sock_strerror(sock_errno()));
+    }
+}
+
+static void
+winsock_start(void)
+{
+    static pthread_once_t once = PTHREAD_ONCE_INIT;
+    pthread_once(&once, do_winsock_start);
+}
+#endif
+
 /* Check the validity of the stream class structures. */
 static void
 check_stream_classes(void)
@@ -207,6 +230,10 @@ stream_open(const char *name, struct stream **streamp, uint8_t dscp)
 
     COVERAGE_INC(stream_open);
 
+#ifdef _WIN32
+    winsock_start();
+#endif
+
     /* Look up the class. */
     error = stream_lookup_class(name, &class);
     if (!class) {
@@ -497,6 +524,10 @@ pstream_open(const char *name, struct pstream **pstreamp, uint8_t dscp)
 
     COVERAGE_INC(pstream_open);
 
+#ifdef _WIN32
+    winsock_start();
+#endif
+
     /* Look up the class. */
     error = pstream_lookup_class(name, &class);
     if (!class) {