Skip to content


Added windows IPv6 support #303

wants to merge 13 commits into from

5 participants


Also increased file and socket limits


@tmm1 just thought I'd let you know that I've completely solved the issues with connection weirdness and eventmachine on windows.

The FD_SETSIZE must be the same on ruby installer as it is in eventmachine.
The next release of ruby installer will increase the limit to 32767 so this must be reflected in project.h
Previous versions of ruby installer ruby will continue to work as they used to.

Thanks for your on going help in the matter. Very much appreciated and helpful.
I'll also stop harassing you now too. ;)

@stakach stakach referenced this pull request in oneclick/rubyinstaller

Low socket limit #104


The ruby installer issue oneclick/rubyinstaller#104


@tmm1 the final product rolled out at Sydney University running on eventmachine and rubyinstaller ruby.
I did a little write up on the project.!topic/rubyinstaller/0UlbSlwXa6U

@stakach stakach referenced this pull request in rubinius/rubinius

Eventmachine Support on Windows #1600

rdp commented

why does it have to match the rubyinstaller FD_SETSIZE again?


From observations on Windows 2008 R2 x64 VM

  • Ruby SETSIZE is enforced
  • Unpredictable behaviour beyond Ruby SETSIZE (at one point I had sockets surviving program termination that remained ESTABLISHED)
  • segfault

actually ruby's extconf system will automagically set this to the higher number for you already, won't it? (i.e. you don't have to set it at all?)

I assume you would have to set it here too as it is compiled independently from ruby then loaded dynamically at run time.

I believe when ruby calls gcc it passes in the "original parameters ruby itself was built with" which includes the -DFD_SETSIZE config.

Ill do a test compile this afternoon and update the pull request.

Wait, we should leave it here as other projects such as will not be including the flag.
See rubinius/rubinius#1600

If other projects don't include it then it should fall back to the default shouldn't it? (otherwise you'll see the descrepancies you noted)?

True that. I'll remove now and update the rubinius issue


have you tested it with rubyinstaller 1.9.3-p194 ?
i'm having some problems with it... see #319.


@stakach Since 8840d22 solves #319 and could be considered a fix this is beyond the scope of just this PR think you could extract it into a new one?


Well the aim of this pull request was to improve windows support on eventmachine.

@tmm1 is there any reason we can't merge these changes and create a new windows release?


@raggi maybe you could help?


Note to self: Check if #570 includes this work.

@sodabrew sodabrew added this to the v1.2.0 milestone

Superseded by #630

@sodabrew sodabrew closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Showing with 63 additions and 11 deletions.
  1. +53 −8 ext/em.cpp
  2. +9 −2 ext/project.h
  3. +1 −1 lib/em/version.rb
61 ext/em.cpp
@@ -97,7 +97,10 @@ EventMachine_t::EventMachine_t (EMCallback event_callback):
#ifdef OS_WIN32
- WSAStartup (MAKEWORD (1, 1), &w);
+ int iResult = WSAStartup (MAKEWORD (1, 1), &w);
+ if(iResult != NO_ERROR)
+ throw std::runtime_error ("WSAStartup function failed");
+ _setmaxstdio(2048);
@@ -130,6 +133,10 @@ EventMachine_t::~EventMachine_t()
close (epfd);
if (kqfd != -1)
close (kqfd);
+ #ifdef OS_WIN32
+ WSACleanup(); // Clean up the windows network library
+ #endif
@@ -1470,14 +1477,50 @@ struct sockaddr *name2address (const char *server, int port, int *family, int *b
#ifdef OS_WIN32
- // TODO, must complete this branch. Windows doesn't have inet_pton.
- // A possible approach is to make a getaddrinfo call with the supplied
- // server address, constraining the hints to ipv6 and seeing if we
- // get any addresses.
- // For the time being, Ipv6 addresses aren't supported on Windows.
- #endif
+ // Windows doesn't have inet_pton.
+ // Make a getaddrinfo call with the supplied server address (hostname or ipv6 address),
+ // We pick the first valid result.
+ struct addrinfo *result = NULL;
+ struct addrinfo *ptr = NULL;
+ //struct addrinfo hints;
+ //memset (&hints, 0, sizeof(hints));
+ //hints.ai_family = AF_UNSPEC; // Hints not needed
+ if(getaddrinfo((char*)server, NULL, NULL, &result) == 0) {
+ for(ptr=result; ptr != NULL; ptr=ptr->ai_next) {
+ switch(ptr->ai_family) {
+ case AF_INET6:
+ memcpy((void*) &in6, (const void*)(ptr->ai_addr), sizeof(in6)); // Copy result
+ freeaddrinfo(result); // Prevent memory leaks
+ if (family)
+ *family = AF_INET6;
+ if (bind_size)
+ *bind_size = sizeof(in6);
+ in6.sin6_family = AF_INET6;
+ in6.sin6_port = htons (port);
+ return (struct sockaddr*)&in6;
+ case AF_INET:
+ memcpy((void*) &in4, (const void*)(ptr->ai_addr), sizeof(in4)); // Copy result
+ freeaddrinfo(result); // Prevent memory leaks
+ if (family)
+ *family = AF_INET;
+ if (bind_size)
+ *bind_size = sizeof(in4);
+ in4.sin_family = AF_INET;
+ in4.sin_port = htons (port);
+ return (struct sockaddr*)&in4;
+ }
+ }
+ }
+ #else
- hp = gethostbyname ((char*)server); // Windows requires the cast.
+ hp = gethostbyname ((char*)server); // Windows requires the cast, although no longer executed on windows
if (hp) {
in4.sin_addr.s_addr = ((in_addr*)(hp->h_addr))->s_addr;
if (family)
@@ -1489,6 +1532,8 @@ struct sockaddr *name2address (const char *server, int port, int *family, int *b
return (struct sockaddr*)&in4;
+ #endif
return NULL;
11 ext/project.h
@@ -81,16 +81,23 @@ typedef int SOCKET;
#endif /* OS_UNIX */
#ifdef OS_WIN32
-// 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
-#define FD_SETSIZE 1024
+// 21Sep09: windows limits select() to 64 sockets by default, we increase here (before including winsock2.h)
+// 27March12: FD_SETSIZE is set at the ruby level and included automatically by extconf
+// #define FD_SETSIZE 32767
+// Add support for IPv6
+#define _WIN32_WINNT 0x501
#include <windows.h>
#include <winsock2.h>
#include <ws2tcpip.h>
#include <rpc.h>
#include <fcntl.h>
#include <assert.h>
+#include <stdio.h>
+// link with Ws2_32.lib
+#pragma comment (lib, "Ws2_32.lib")
typedef int socklen_t;
typedef int pid_t;
2 lib/em/version.rb
@@ -1,3 +1,3 @@
module EventMachine
- VERSION = "1.0.0.beta.4"
+ VERSION = "1.0.0.beta.5"
Something went wrong with that request. Please try again.