Skip to content


Subversion checkout URL

You can clone with
Download ZIP


win32 issues #1

deepj opened this Issue · 14 comments

9 participants


won't build


it doesn't even install under mingw ruby 1.9.1 and gcc 3.4.5 and eventmachine 0.12.9. i get the same error as above

g++ -I. -Ic:/Ruby/include/ruby-1.9.1/i386-mingw32 -I/c/Ruby/include/ruby-1.9.1/ruby/backward -I/c/Ruby/include/ruby-1.9.1 -I. -DBUILD_FOR_RUBY -DHAVE_RB_THREAD_BLOCKING_REGION -DHAVE_TBR -DOS_WIN32 -DHAVE_WINDOWS_H -DHAVE_WINSOCK_H -DWITHOUT_SSL    -O2 -g -Wall -Wno-parentheses     -o binder.o -c binder.cpp
In file included from binder.cpp:20:
project.h:26: warning: ignoring #pragma warning 
g++ -I. -Ic:/Ruby/include/ruby-1.9.1/i386-mingw32 -I/c/Ruby/include/ruby-1.9.1/ruby/backward -I/c/Ruby/include/ruby-1.9.1 -I. -DBUILD_FOR_RUBY -DHAVE_RB_THREAD_BLOCKING_REGION -DHAVE_TBR -DOS_WIN32 -DHAVE_WINDOWS_H -DHAVE_WINSOCK_H -DWITHOUT_SSL    -O2 -g -Wall -Wno-parentheses     -o cmain.o -c cmain.cpp
In file included from cmain.cpp:20:
project.h:26: warning: ignoring #pragma warning 
cmain.cpp:595:2: warning: "/*" within comment
cmain.cpp: In function `int evma_send_file_data_to_connection(const char*, const char*)':
cmain.cpp:610: error: cannot convert `_stati64*' to `stat*' for argument `2' to `int fstat(int, stat*)'
cmain.cpp:621: warning: comparison between signed and unsigned integer expressions
make: *** [cmain.o] Error 1
is another possible patch, trying to figure it out still


Try with the latest git master?


I've tried the last version in git master now and it still is the same problem with "error: cannot convert_stati64' ...".


Looks like you need to add a #undef stat to cmain.cpp somewhere (before line 610). With that change it compiles for me.


yes,add a #undef stat to cmain.cpp before line "struct stat st; " will work,could this line be add to the git source?


I was able to get Ruby 1.9.2 on Windows running with the latest github version of EventMachine and also SSL support. Here's a post that I sent to the rubyinstaller group:

Ruby 1.9.2, Windows, EventMachine, and SSL



I now have Ruby 1.9.2 on Windows with a clean, working, latest github
version of EventMachine running with OpenSSL support (so that https
requests finally work!).

The problem is that EventMachine for SSL is trying to link and use
OpenSSL, and is not there. It needs OpenSSL development headers and

Fortunately, when using rubyinstaller to build Ruby 1.9.2, these
libraries and header files are either compiled or otherwise made
available on the local machine. The question is how do we simply refer
to them when compiling EventMachine?

As a workaround, you can try building and installing EventMachine
against sandbox/openssl:

gem install eventmachine -- --with-openssl-dir=....

This is very close, but it actually wanted "--with-ssl-dir..." instead
of "--with-openssl-dir=...".

NOTE: In order for the below to work, I had to first clone the github
repository for rubyinstaller. Using that, I compiled and installed a
fresh Ruby 1.9.2 (using 'rake ruby19') and DevKit (using 'rake devkit
SFX=1' and then installed the "DevKit-4.5.0-{timestamp}-sfx.exe" file
it generates). There's a little setup required to get DevKit properly
configured (see the Wiki on the rubyinstaller project, where DevKit is

Without further ado, here's what I did to get EventMachine running on
Ruby 1.9.2 on Windows with SSL support:

D:\Code\Gems>git clone
Cloning into eventmachine...
remote: Counting objects: 3404, done.
remote: Compressing objects: 100% (1195/1195), done.
remote: Total 3404 (delta 2454), reused 2976 (delta 2084)
Receiving objects: 100% (3404/3404), 701.70 KiB | 423 KiB/s, done.
Resolving deltas: 100% (2454/2454), done.

D:\Code\Gems>cd eventmachine

D:\Code\Gems\eventmachine>gem build eventmachine.gemspec
  Successfully built RubyGem
  Name: eventmachine
  Version: 0.12.11
  File: eventmachine-0.12.11.gem

D:\Code\Gems\eventmachine>gem install eventmachine-0.12.11.gem -- --with-ssl-dir=d:/Code/rubyinstaller/sandbox/openssl
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
Successfully installed eventmachine-0.12.11
1 gem installed

D:\Code\Gems\eventmachine>gem install em-http-request
Temporarily enhancing PATH to include DevKit...
Building native extensions.  This could take a while...
Successfully installed em-http-request-0.2.11
1 gem installed

D:\Code\Gems\eventmachine>ruby bank.rb
{"DATE"=>"Fri, 20 Aug 2010 17:09:03 GMT",
"SERVER"=>"IBM_HTTP_Server", ... the rest of the request!

The source for bank.rb is:

require 'em-http-request' {
  http =

  http.callback {
    p http.response_header.status
    p http.response_header
    p http.response


I hope this is helpful to others. Also, I hope the EventMachine
maintainers update the standard rubygems version soon so that it works
with Ruby 1.9.2 on Windows.

It is the right place to ask, and thank you for doing your homework
and investigating the issue. However, we might not have the control or
the manpower to change every gem out there to make it more easy to
support Windows.

I agree. EventMachine is such an important gem, however, that it might
warrant a little extra attention. Hopefully, we're good to go from now

Hope my answer somehow helps.

Thanks Luis for all of your help!




Confirmed, with most recent rubyinstaller (ruby 1.9.2p0 (2010-08-18) [i386-mingw32]) it installs successfully from github source. I use it with em-websocket gem. Updating rubygem version would be much appreciated. Thanks guys!



Could you paste the exact commands you entered at the command line to get this to compile? It would be helpful to see how a 'stock' ruby 1.9.2p0 installation can be used to compile eventmachine with SSL support.



I used exactly the same commands that you pasted, but without "--with-ssl-dir" option


I believe it will work without the "--with-ssl-dir" option, but there won't be any HTTPS/SSL support.

I made a temporary little repo on github to show what I did to get HTTPS/SSL
support working for EventMachine using the stock Ruby 1.9.2p0
installer that you made. Essentially, I used the output from compiling
ruby 1.9.2 using the rubyinstaller from github and then just grabbed
the openssl include directory and two of the compiled files in the lib
directory to create a minimal set of files required for me to compile
and run an SSL-enabled EventMachine using the stock ruby 1.9.2p0
installer that you released. Here's the link to the temporary repo:

Given that EventMachine is required for many other libraries (eg -
thin), it would be great to easily support it. What I have done in the
repo above works, but there must be a better way to do it.

Luis (of rubyinstaller fame) says we should look at what the postgres guys did. He says that they use rake-compiler to cross compile support libraries like openssl for their gem:

Perhaps one of the eventmachine maintainers could mirror what they've done so that Windows users of Ruby 1.9.2 could get HTTPS/SSL support out of the box.


+1 for updating the windows binary gem to work with 1.9.2




I just pushed an EM 1.0.0.beta.2 binary gem, install it using gem install eventmachine --pre

This should work on both 1.8 and 1.9, and includes openssl support. Please test, and open new issues if you run into any problems.

@nijopa nijopa referenced this issue from a commit in nijopa/eventmachine

NB - this commit message is repeated in file ext/ed.cpp
to act as a comment for future maintainers.


Operating system version

Operating system : centos 6 on AMD x86_64 arch
Kernel version:
  >> uname -a
  >> Linux localhost.localdomain 2.6.32-71.el6.x86_64 #1 SMP Fri May 20 03:51:51 BST 2011 x86_64 x86_64 x86_64 GNU/Linux

Ruby version

  >> ruby --version
  >> ruby 1.9.2p290 (2011-07-09 revision 32553) [x86_64-linux]

Problem Description

We detected this problem while developing a client/server job
distribution system for a scientific computing application.

We have a very large LSF compute cluster which we use to
process compute-intensive tasks.  The job distribution system
gets a compute slot on LSF where a client is launched.  The
client then rings back to the server and asks for work, which
is subsequently launched as a sub-process of the client.

We found that we were getting clients 'stuck' on compute
slots, without any associated workload being processed. These
clients would live forever, taking up capacity on our LSF
cluster, which in turn reduced throughput for other users of
the cluster.

An initial investigation showed that these client processes
did not appear to have any corresponding server process.

There was a TCP socket open on the client host to the machine
which had hosted the server process, but apparently no
corresponding socket on the server host.


We knew that users had started killing the server process for
their jobs in order to launch newer, fresher workloads.

LSF uses a sequence of signals to both warn a job that it is
about to be shut down, and to ensure that the job really does
terminate. The sequence is as follows:

  SIGINT -> SIGTERM -> SIGKILL (separated by a time of 10s)

We know that the server application traps SIGINT and SIGTERM
signals, so it seemed likely that the problem was an incomplete
shutdown under SIGKILL conditions.

We need to use EM.system() to launch sub processes from the
server in order to launch the clients into the compute
cluster.  Access to the LSF cluster is via vanilla
user-facing tools (eg bsub, bjobs, bkill etc etc).

The full scenario is as follows:

  1) server launches client into lsf with EM.system("bsub ...")
  2) EM goes off to handle other tasks while the bsub is running
  3) Time passes...
  4) server uses EM.system() to do some other time consuming job
  5) While this is running, one or more client processes ring home
     to get their next workloads
  6) User decides to terminate their current set of jobs and issues
     a 'bkill' operation, assuming that this will also kill the clients.
     (NB - the clients do have a heartbeat mechanism to detect the
     death of the server)
  7) LSF starts killing the server (the EM.system is still running)
  8) LSF eventually uses SIGKILL to ensure a full kill

>> wedged client processes!


We were able to reproduce the scenario by writing a simple
EventMachine::HttpServer server and using standard tools
such as 'wget' to connect to the server.

When the server got an incoming request, it launched a
time consuming sub-process such as '/bin/sleep 3600'
via EM.system().

We were able to confirm that EM launched the 'sleep' in such a
way that it wasn't blocking the wider EM event processing
loop. We could also see the 'sleep' as a subprocess of ruby,
along with processes for the 20 threads spawned by EM.

We also confirmed that the TCP connection was attached to the
server as you would expect:

  lsof -p 28915
  ruby    28915 nick  cwd    DIR              253,0     4096  532885 /home/nick/Work/ruby_event_machine_tests
  ... snip ...
  ruby    28915 nick    5u  IPv4             156947      0t0     TCP *:tproxy (LISTEN)
  ruby    28915 nick    6u  IPv4             157383      0t0     TCP localhost.localdomain:tproxy->loca

We then issued a SIGKILL (kill -9) to the server process.

We saw that the server process died, as you would expect,
since SIGKILL is not trappable.

We also saw that the 'sleep' process was still in existance,
but orphaned, so therefore attached to PID 1.

However, we also saw that the 'wget' client did not detach
from its socket when the server died. We also saw that the
'sleep' process had a copy of the TCP connection between
the 'wget' client and the (now dead) server.

For example:

  lsof -p 28955
  sleep   28955 nick  cwd    DIR              253,0     4096 532885 /home/nick/Work/ruby_event_machine_tests
  sleep   28955 nick  txt    REG              253,0    27880 132819 /bin/sleep
  ... snip ...
  sleep   28955 nick    6u  IPv4             157383      0t0    TCP localhost.localdomain:tproxy->localhost.localdomain:50903 (ESTABLISHED)

  We validated that the 'wget' client did indeed terminate when
  the 'sleep' process was terminated.

  So, how did a 'sleep' process end up getting a TCP connection??

Root cause

The root cause is the handling of the FD_CLOEXEC property on the
file descriptors which represent the TCP connections onto the server.

If you look at the 'lsof' for process 28915 output above,
you'll see that the server actually has 2 file descriptors

  6) TCP connection ESTABLISHED

When you look at the 'sleep' process (PID 28955), you see the
ESTABLISHED connection but you'll notice that it's file
descriptor '6'. File descriptor '5' has been closed.

This is what we'd expect to see, given that FD_CLOEXEC is set
on the file descriptor which was originally created when the
TCP server was initialized.

You can find this code in file 'em.cpp'
at line 1533 (in method EventMachine_t::CreateTcpServer) in
the eventmachine-1.0.0.beta.4 release.

However, the file descriptor '6' appears to have been inheritted,
which suggests that it didn't have FD_CLOEXEC set on it.


I tracked the generation of the new file descriptor down to
the 'accept' statement on line 1410 in this file (above).

The fix is to simply set the FD_CLOEXEC property on the new file
descriptor, in exactly the same way as done in file em.cpp:1533.

In testing, this does solve the inheritance of file
descriptors by child processes and allows the client 'wget'
process to die as soon as the server process is killed.

What this fix does not address

This fix will still allow the child process to be orhpaned.

It also does not address what the long-running process launched
by the server was, that stayed alive so long that the clients
never appeared to terminate. That's a workload issue which we'll
need to resolve ourselves.

Questions / Possible issues

While this fix solves my specific problem, I don't know whether
this will cause problems for other EM workloads.

Does this fix go against any design philosophy of EventMachine?
Was it deliberate that FD_CLOEXEC wasn't set against the new
file descriptor?

Do any sub-processes launched with EM.system() depend on accessing
the TCP socket opened by its parent?
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.