eventmachine 1.0.0.beta.4-x86-mingw32 → 1.0.0.rc.1-x86-mingw32
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Rakefile +11 -10
 - data/eventmachine.gemspec +1 -1
 - data/ext/cmain.cpp +38 -0
 - data/ext/ed.cpp +18 -1
 - data/ext/ed.h +5 -0
 - data/ext/em.cpp +30 -7
 - data/ext/em.h +3 -2
 - data/ext/eventmachine.h +4 -0
 - data/ext/extconf.rb +11 -2
 - data/ext/fastfilereader/extconf.rb +10 -1
 - data/ext/project.h +2 -1
 - data/ext/rubymain.cpp +56 -6
 - data/ext/ssl.cpp +4 -1
 - data/java/src/com/rubyeventmachine/EmReactor.java +4 -0
 - data/java/src/com/rubyeventmachine/EventableChannel.java +1 -0
 - data/java/src/com/rubyeventmachine/EventableDatagramChannel.java +6 -0
 - data/java/src/com/rubyeventmachine/EventableSocketChannel.java +6 -0
 - data/lib/em/connection.rb +11 -0
 - data/lib/em/pool.rb +7 -2
 - data/lib/em/protocols/smtpclient.rb +28 -28
 - data/lib/em/threaded_resource.rb +1 -1
 - data/lib/em/version.rb +1 -1
 - data/lib/eventmachine.rb +57 -11
 - data/lib/jeventmachine.rb +5 -0
 - data/{tasks → rakelib}/cpp.rake_example +0 -0
 - data/{tasks → rakelib}/package.rake +0 -0
 - data/{tasks → rakelib}/test.rake +0 -0
 - data/tests/test_basic.rb +67 -0
 - data/tests/test_idle_connection.rb +23 -0
 - data/tests/test_pool.rb +67 -1
 - data/tests/test_proxy_connection.rb +13 -1
 - data/tests/test_unbind_reason.rb +19 -2
 - metadata +9 -22
 
    
        data/Rakefile
    CHANGED
    
    | 
         @@ -1,10 +1,6 @@ 
     | 
|
| 
       1 
     | 
    
         
            -
            require 'rubygems' 
     | 
| 
       2 
     | 
    
         
            -
             
     | 
| 
       3 
     | 
    
         
            -
            import  *Dir['tasks/*.rake']
         
     | 
| 
      
 1 
     | 
    
         
            +
            require 'rubygems'
         
     | 
| 
      
 2 
     | 
    
         
            +
            GEMSPEC = Gem::Specification.load('eventmachine.gemspec')
         
     | 
| 
       4 
3 
     | 
    
         | 
| 
       5 
     | 
    
         
            -
            GEMSPEC = eval(File.read(File.expand_path('../eventmachine.gemspec', __FILE__)))
         
     | 
| 
       6 
     | 
    
         
            -
             
     | 
| 
       7 
     | 
    
         
            -
            require 'yard'
         
     | 
| 
       8 
4 
     | 
    
         
             
            require 'rake/clean'
         
     | 
| 
       9 
5 
     | 
    
         
             
            task :clobber => :clean
         
     | 
| 
       10 
6 
     | 
    
         | 
| 
         @@ -12,8 +8,13 @@ desc "Build eventmachine, then run tests." 
     | 
|
| 
       12 
8 
     | 
    
         
             
            task :default => [:compile, :test]
         
     | 
| 
       13 
9 
     | 
    
         | 
| 
       14 
10 
     | 
    
         
             
            desc 'Generate documentation'
         
     | 
| 
       15 
     | 
    
         
            -
             
     | 
| 
       16 
     | 
    
         
            -
               
     | 
| 
       17 
     | 
    
         
            -
               
     | 
| 
       18 
     | 
    
         
            -
             
     | 
| 
      
 11 
     | 
    
         
            +
            begin
         
     | 
| 
      
 12 
     | 
    
         
            +
              require 'yard'
         
     | 
| 
      
 13 
     | 
    
         
            +
              YARD::Rake::YardocTask.new do |t|
         
     | 
| 
      
 14 
     | 
    
         
            +
                t.files   = ['lib/**/*.rb', '-', 'docs/*.md']
         
     | 
| 
      
 15 
     | 
    
         
            +
                t.options = ['--main', 'README.md', '--no-private']
         
     | 
| 
      
 16 
     | 
    
         
            +
                t.options = ['--exclude', 'lib/jeventmachine', '--exclude', 'lib/pr_eventmachine']
         
     | 
| 
      
 17 
     | 
    
         
            +
              end
         
     | 
| 
      
 18 
     | 
    
         
            +
            rescue LoadError
         
     | 
| 
      
 19 
     | 
    
         
            +
              task :yard do puts "Please install yard first!"; end
         
     | 
| 
       19 
20 
     | 
    
         
             
            end
         
     | 
    
        data/eventmachine.gemspec
    CHANGED
    
    | 
         @@ -15,7 +15,7 @@ Gem::Specification.new do |s| 
     | 
|
| 
       15 
15 
     | 
    
         | 
| 
       16 
16 
     | 
    
         
             
              s.add_development_dependency 'rake-compiler', '0.7.9'
         
     | 
| 
       17 
17 
     | 
    
         
             
              s.add_development_dependency 'yard', ">= 0.7.2"
         
     | 
| 
       18 
     | 
    
         
            -
              s.add_development_dependency 'bluecloth'
         
     | 
| 
      
 18 
     | 
    
         
            +
              #s.add_development_dependency 'bluecloth'
         
     | 
| 
       19 
19 
     | 
    
         | 
| 
       20 
20 
     | 
    
         
             
              s.summary = 'Ruby/EventMachine library'
         
     | 
| 
       21 
21 
     | 
    
         
             
              s.description = "EventMachine implements a fast, single-threaded engine for arbitrary network
         
     | 
    
        data/ext/cmain.cpp
    CHANGED
    
    | 
         @@ -253,6 +253,15 @@ extern "C" int evma_is_paused (const unsigned long binding) 
     | 
|
| 
       253 
253 
     | 
    
         
             
            	return 0;
         
     | 
| 
       254 
254 
     | 
    
         
             
            }
         
     | 
| 
       255 
255 
     | 
    
         | 
| 
      
 256 
     | 
    
         
            +
            /************************
         
     | 
| 
      
 257 
     | 
    
         
            +
            evma_num_close_scheduled
         
     | 
| 
      
 258 
     | 
    
         
            +
            ************************/
         
     | 
| 
      
 259 
     | 
    
         
            +
             
     | 
| 
      
 260 
     | 
    
         
            +
            extern "C" int evma_num_close_scheduled ()
         
     | 
| 
      
 261 
     | 
    
         
            +
            {
         
     | 
| 
      
 262 
     | 
    
         
            +
            	return EventMachine->NumCloseScheduled;
         
     | 
| 
      
 263 
     | 
    
         
            +
            }
         
     | 
| 
      
 264 
     | 
    
         
            +
             
     | 
| 
       256 
265 
     | 
    
         
             
            /**********************
         
     | 
| 
       257 
266 
     | 
    
         
             
            evma_create_tcp_server
         
     | 
| 
       258 
267 
     | 
    
         
             
            **********************/
         
     | 
| 
         @@ -804,6 +813,35 @@ extern "C" void evma_stop_proxy (const unsigned long from) 
     | 
|
| 
       804 
813 
     | 
    
         
             
            		ed->StopProxy();
         
     | 
| 
       805 
814 
     | 
    
         
             
            }
         
     | 
| 
       806 
815 
     | 
    
         | 
| 
      
 816 
     | 
    
         
            +
            /******************
         
     | 
| 
      
 817 
     | 
    
         
            +
            evma_proxied_bytes
         
     | 
| 
      
 818 
     | 
    
         
            +
            *******************/
         
     | 
| 
      
 819 
     | 
    
         
            +
             
     | 
| 
      
 820 
     | 
    
         
            +
            extern "C" unsigned long evma_proxied_bytes (const unsigned long from)
         
     | 
| 
      
 821 
     | 
    
         
            +
            {
         
     | 
| 
      
 822 
     | 
    
         
            +
            	ensure_eventmachine("evma_proxied_bytes");
         
     | 
| 
      
 823 
     | 
    
         
            +
            	EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
         
     | 
| 
      
 824 
     | 
    
         
            +
            	if (ed)
         
     | 
| 
      
 825 
     | 
    
         
            +
            		return ed->GetProxiedBytes();
         
     | 
| 
      
 826 
     | 
    
         
            +
            	else
         
     | 
| 
      
 827 
     | 
    
         
            +
            		return 0;
         
     | 
| 
      
 828 
     | 
    
         
            +
            }
         
     | 
| 
      
 829 
     | 
    
         
            +
             
     | 
| 
      
 830 
     | 
    
         
            +
             
     | 
| 
      
 831 
     | 
    
         
            +
            /***************************
         
     | 
| 
      
 832 
     | 
    
         
            +
            evma_get_last_activity_time
         
     | 
| 
      
 833 
     | 
    
         
            +
            ****************************/
         
     | 
| 
      
 834 
     | 
    
         
            +
             
     | 
| 
      
 835 
     | 
    
         
            +
            extern "C" uint64_t evma_get_last_activity_time(const unsigned long from)
         
     | 
| 
      
 836 
     | 
    
         
            +
            {
         
     | 
| 
      
 837 
     | 
    
         
            +
            	ensure_eventmachine("evma_get_last_activity_time");
         
     | 
| 
      
 838 
     | 
    
         
            +
            	EventableDescriptor *ed = dynamic_cast <EventableDescriptor*> (Bindable_t::GetObject (from));
         
     | 
| 
      
 839 
     | 
    
         
            +
            	if (ed)
         
     | 
| 
      
 840 
     | 
    
         
            +
            		return ed->GetLastActivity();
         
     | 
| 
      
 841 
     | 
    
         
            +
            	else
         
     | 
| 
      
 842 
     | 
    
         
            +
            		return 0;
         
     | 
| 
      
 843 
     | 
    
         
            +
            }
         
     | 
| 
      
 844 
     | 
    
         
            +
             
     | 
| 
       807 
845 
     | 
    
         | 
| 
       808 
846 
     | 
    
         
             
            /***************************
         
     | 
| 
       809 
847 
     | 
    
         
             
            evma_get_heartbeat_interval
         
     | 
    
        data/ext/ed.cpp
    CHANGED
    
    | 
         @@ -54,12 +54,14 @@ EventableDescriptor::EventableDescriptor (int sd, EventMachine_t *em): 
     | 
|
| 
       54 
54 
     | 
    
         
             
            	bCloseNow (false),
         
     | 
| 
       55 
55 
     | 
    
         
             
            	bCloseAfterWriting (false),
         
     | 
| 
       56 
56 
     | 
    
         
             
            	MySocket (sd),
         
     | 
| 
      
 57 
     | 
    
         
            +
            	bAttached (false),
         
     | 
| 
       57 
58 
     | 
    
         
             
            	bWatchOnly (false),
         
     | 
| 
       58 
59 
     | 
    
         
             
            	EventCallback (NULL),
         
     | 
| 
       59 
60 
     | 
    
         
             
            	bCallbackUnbind (true),
         
     | 
| 
       60 
61 
     | 
    
         
             
            	UnbindReasonCode (0),
         
     | 
| 
       61 
62 
     | 
    
         
             
            	ProxyTarget(NULL),
         
     | 
| 
       62 
63 
     | 
    
         
             
            	ProxiedFrom(NULL),
         
     | 
| 
      
 64 
     | 
    
         
            +
            	ProxiedBytes(0),
         
     | 
| 
       63 
65 
     | 
    
         
             
            	MaxOutboundBufSize(0),
         
     | 
| 
       64 
66 
     | 
    
         
             
            	MyEventMachine (em),
         
     | 
| 
       65 
67 
     | 
    
         
             
            	PendingConnectTimeout(20000000),
         
     | 
| 
         @@ -115,6 +117,7 @@ EventableDescriptor::~EventableDescriptor() 
     | 
|
| 
       115 
117 
     | 
    
         
             
            		(*EventCallback)(ProxiedFrom->GetBinding(), EM_PROXY_TARGET_UNBOUND, NULL, 0);
         
     | 
| 
       116 
118 
     | 
    
         
             
            		ProxiedFrom->StopProxy();
         
     | 
| 
       117 
119 
     | 
    
         
             
            	}
         
     | 
| 
      
 120 
     | 
    
         
            +
            	MyEventMachine->NumCloseScheduled--;
         
     | 
| 
       118 
121 
     | 
    
         
             
            	StopProxy();
         
     | 
| 
       119 
122 
     | 
    
         
             
            	Close();
         
     | 
| 
       120 
123 
     | 
    
         
             
            }
         
     | 
| 
         @@ -179,7 +182,7 @@ void EventableDescriptor::Close() 
     | 
|
| 
       179 
182 
     | 
    
         
             
            		MyEventMachine->Deregister (this);
         
     | 
| 
       180 
183 
     | 
    
         | 
| 
       181 
184 
     | 
    
         
             
            		// Do not close STDIN, STDOUT, STDERR
         
     | 
| 
       182 
     | 
    
         
            -
            		if (MySocket > 2 && ! 
     | 
| 
      
 185 
     | 
    
         
            +
            		if (MySocket > 2 && !bAttached) {
         
     | 
| 
       183 
186 
     | 
    
         
             
            			shutdown (MySocket, 1);
         
     | 
| 
       184 
187 
     | 
    
         
             
            			close (MySocket);
         
     | 
| 
       185 
188 
     | 
    
         
             
            		}
         
     | 
| 
         @@ -214,6 +217,7 @@ EventableDescriptor::ScheduleClose 
     | 
|
| 
       214 
217 
     | 
    
         | 
| 
       215 
218 
     | 
    
         
             
            void EventableDescriptor::ScheduleClose (bool after_writing)
         
     | 
| 
       216 
219 
     | 
    
         
             
            {
         
     | 
| 
      
 220 
     | 
    
         
            +
            	MyEventMachine->NumCloseScheduled++;
         
     | 
| 
       217 
221 
     | 
    
         
             
            	// KEEP THIS SYNCHRONIZED WITH ::IsCloseScheduled.
         
     | 
| 
       218 
222 
     | 
    
         
             
            	if (after_writing)
         
     | 
| 
       219 
223 
     | 
    
         
             
            		bCloseAfterWriting = true;
         
     | 
| 
         @@ -244,6 +248,7 @@ void EventableDescriptor::StartProxy(const unsigned long to, const unsigned long 
     | 
|
| 
       244 
248 
     | 
    
         
             
            		StopProxy();
         
     | 
| 
       245 
249 
     | 
    
         
             
            		ProxyTarget = ed;
         
     | 
| 
       246 
250 
     | 
    
         
             
            		BytesToProxy = length;
         
     | 
| 
      
 251 
     | 
    
         
            +
            		ProxiedBytes = 0;
         
     | 
| 
       247 
252 
     | 
    
         
             
            		ed->SetProxiedFrom(this, bufsize);
         
     | 
| 
       248 
253 
     | 
    
         
             
            		return;
         
     | 
| 
       249 
254 
     | 
    
         
             
            	}
         
     | 
| 
         @@ -290,6 +295,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size) 
     | 
|
| 
       290 
295 
     | 
    
         
             
            		if (BytesToProxy > 0) {
         
     | 
| 
       291 
296 
     | 
    
         
             
            			unsigned long proxied = min(BytesToProxy, (unsigned long) size);
         
     | 
| 
       292 
297 
     | 
    
         
             
            			ProxyTarget->SendOutboundData(buf, proxied);
         
     | 
| 
      
 298 
     | 
    
         
            +
            			ProxiedBytes += (unsigned long) proxied;
         
     | 
| 
       293 
299 
     | 
    
         
             
            			BytesToProxy -= proxied;
         
     | 
| 
       294 
300 
     | 
    
         
             
            			if (BytesToProxy == 0) {
         
     | 
| 
       295 
301 
     | 
    
         
             
            				StopProxy();
         
     | 
| 
         @@ -300,6 +306,7 @@ void EventableDescriptor::_GenericInboundDispatch(const char *buf, int size) 
     | 
|
| 
       300 
306 
     | 
    
         
             
            			}
         
     | 
| 
       301 
307 
     | 
    
         
             
            		} else {
         
     | 
| 
       302 
308 
     | 
    
         
             
            			ProxyTarget->SendOutboundData(buf, size);
         
     | 
| 
      
 309 
     | 
    
         
            +
            			ProxiedBytes += (unsigned long) size;
         
     | 
| 
       303 
310 
     | 
    
         
             
            		}
         
     | 
| 
       304 
311 
     | 
    
         
             
            	} else {
         
     | 
| 
       305 
312 
     | 
    
         
             
            		(*EventCallback)(GetBinding(), EM_CONNECTION_READ, buf, size);
         
     | 
| 
         @@ -457,6 +464,16 @@ void ConnectionDescriptor::SetConnectPending(bool f) 
     | 
|
| 
       457 
464 
     | 
    
         
             
            }
         
     | 
| 
       458 
465 
     | 
    
         | 
| 
       459 
466 
     | 
    
         | 
| 
      
 467 
     | 
    
         
            +
            /**********************************
         
     | 
| 
      
 468 
     | 
    
         
            +
            ConnectionDescriptor::SetAttached
         
     | 
| 
      
 469 
     | 
    
         
            +
            ***********************************/
         
     | 
| 
      
 470 
     | 
    
         
            +
             
     | 
| 
      
 471 
     | 
    
         
            +
            void ConnectionDescriptor::SetAttached(bool state)
         
     | 
| 
      
 472 
     | 
    
         
            +
            {
         
     | 
| 
      
 473 
     | 
    
         
            +
               bAttached = state;
         
     | 
| 
      
 474 
     | 
    
         
            +
            }
         
     | 
| 
      
 475 
     | 
    
         
            +
             
     | 
| 
      
 476 
     | 
    
         
            +
             
     | 
| 
       460 
477 
     | 
    
         
             
            /**********************************
         
     | 
| 
       461 
478 
     | 
    
         
             
            ConnectionDescriptor::SetWatchOnly
         
     | 
| 
       462 
479 
     | 
    
         
             
            ***********************************/
         
     | 
    
        data/ext/ed.h
    CHANGED
    
    | 
         @@ -79,6 +79,7 @@ class EventableDescriptor: public Bindable_t 
     | 
|
| 
       79 
79 
     | 
    
         
             
            		virtual int SetCommInactivityTimeout (uint64_t value) {return 0;}
         
     | 
| 
       80 
80 
     | 
    
         
             
            		uint64_t GetPendingConnectTimeout();
         
     | 
| 
       81 
81 
     | 
    
         
             
            		int SetPendingConnectTimeout (uint64_t value);
         
     | 
| 
      
 82 
     | 
    
         
            +
            		uint64_t GetLastActivity() { return LastActivity; }
         
     | 
| 
       82 
83 
     | 
    
         | 
| 
       83 
84 
     | 
    
         
             
            		#ifdef HAVE_EPOLL
         
     | 
| 
       84 
85 
     | 
    
         
             
            		struct epoll_event *GetEpollEvent() { return &EpollEvent; }
         
     | 
| 
         @@ -86,6 +87,7 @@ class EventableDescriptor: public Bindable_t 
     | 
|
| 
       86 
87 
     | 
    
         | 
| 
       87 
88 
     | 
    
         
             
            		virtual void StartProxy(const unsigned long, const unsigned long, const unsigned long);
         
     | 
| 
       88 
89 
     | 
    
         
             
            		virtual void StopProxy();
         
     | 
| 
      
 90 
     | 
    
         
            +
            		virtual unsigned long GetProxiedBytes(){ return ProxiedBytes; };
         
     | 
| 
       89 
91 
     | 
    
         
             
            		virtual void SetProxiedFrom(EventableDescriptor*, const unsigned long);
         
     | 
| 
       90 
92 
     | 
    
         
             
            		virtual int SendOutboundData(const char*,int){ return -1; }
         
     | 
| 
       91 
93 
     | 
    
         
             
            		virtual bool IsPaused(){ return bPaused; }
         
     | 
| 
         @@ -103,6 +105,7 @@ class EventableDescriptor: public Bindable_t 
     | 
|
| 
       103 
105 
     | 
    
         | 
| 
       104 
106 
     | 
    
         
             
            	protected:
         
     | 
| 
       105 
107 
     | 
    
         
             
            		int MySocket;
         
     | 
| 
      
 108 
     | 
    
         
            +
            		bool bAttached;
         
     | 
| 
       106 
109 
     | 
    
         
             
            		bool bWatchOnly;
         
     | 
| 
       107 
110 
     | 
    
         | 
| 
       108 
111 
     | 
    
         
             
            		EMCallback EventCallback;
         
     | 
| 
         @@ -115,6 +118,7 @@ class EventableDescriptor: public Bindable_t 
     | 
|
| 
       115 
118 
     | 
    
         
             
            		unsigned long BytesToProxy;
         
     | 
| 
       116 
119 
     | 
    
         
             
            		EventableDescriptor *ProxyTarget;
         
     | 
| 
       117 
120 
     | 
    
         
             
            		EventableDescriptor *ProxiedFrom;
         
     | 
| 
      
 121 
     | 
    
         
            +
            		unsigned long ProxiedBytes;
         
     | 
| 
       118 
122 
     | 
    
         | 
| 
       119 
123 
     | 
    
         
             
            		unsigned long MaxOutboundBufSize;
         
     | 
| 
       120 
124 
     | 
    
         | 
| 
         @@ -169,6 +173,7 @@ class ConnectionDescriptor: public EventableDescriptor 
     | 
|
| 
       169 
173 
     | 
    
         | 
| 
       170 
174 
     | 
    
         
             
            		void SetNotifyReadable (bool);
         
     | 
| 
       171 
175 
     | 
    
         
             
            		void SetNotifyWritable (bool);
         
     | 
| 
      
 176 
     | 
    
         
            +
            		void SetAttached (bool);
         
     | 
| 
       172 
177 
     | 
    
         
             
            		void SetWatchOnly (bool);
         
     | 
| 
       173 
178 
     | 
    
         | 
| 
       174 
179 
     | 
    
         
             
            		bool Pause();
         
     | 
    
        data/ext/em.cpp
    CHANGED
    
    | 
         @@ -73,6 +73,7 @@ EventMachine_t::EventMachine_t (EMCallback event_callback): 
     | 
|
| 
       73 
73 
     | 
    
         
             
            	NextHeartbeatTime (0),
         
     | 
| 
       74 
74 
     | 
    
         
             
            	LoopBreakerReader (-1),
         
     | 
| 
       75 
75 
     | 
    
         
             
            	LoopBreakerWriter (-1),
         
     | 
| 
      
 76 
     | 
    
         
            +
            	NumCloseScheduled (0),
         
     | 
| 
       76 
77 
     | 
    
         
             
            	bTerminateSignalReceived (false),
         
     | 
| 
       77 
78 
     | 
    
         
             
            	bEpoll (false),
         
     | 
| 
       78 
79 
     | 
    
         
             
            	epfd (-1),
         
     | 
| 
         @@ -197,10 +198,9 @@ EventMachine_t::SetTimerQuantum 
     | 
|
| 
       197 
198 
     | 
    
         
             
            void EventMachine_t::SetTimerQuantum (int interval)
         
     | 
| 
       198 
199 
     | 
    
         
             
            {
         
     | 
| 
       199 
200 
     | 
    
         
             
            	/* We get a timer-quantum expressed in milliseconds.
         
     | 
| 
       200 
     | 
    
         
            -
            	 * Don't set a quantum smaller than 5 or larger than 2500.
         
     | 
| 
       201 
201 
     | 
    
         
             
            	 */
         
     | 
| 
       202 
202 
     | 
    
         | 
| 
       203 
     | 
    
         
            -
            	if ((interval < 5) || (interval >  
     | 
| 
      
 203 
     | 
    
         
            +
            	if ((interval < 5) || (interval > 5*60*1000))
         
     | 
| 
       204 
204 
     | 
    
         
             
            		throw std::runtime_error ("invalid timer-quantum");
         
     | 
| 
       205 
205 
     | 
    
         | 
| 
       206 
206 
     | 
    
         
             
            	Quantum.tv_sec = interval / 1000;
         
     | 
| 
         @@ -673,7 +673,13 @@ EventMachine_t::_TimeTilNextEvent 
     | 
|
| 
       673 
673 
     | 
    
         | 
| 
       674 
674 
     | 
    
         
             
            timeval EventMachine_t::_TimeTilNextEvent()
         
     | 
| 
       675 
675 
     | 
    
         
             
            {
         
     | 
| 
      
 676 
     | 
    
         
            +
            	// 29jul11: Changed calculation base from MyCurrentLoopTime to the 
         
     | 
| 
      
 677 
     | 
    
         
            +
            	// real time. As MyCurrentLoopTime is set at the beginning of an
         
     | 
| 
      
 678 
     | 
    
         
            +
            	// iteration and this calculation is done at the end, evenmachine
         
     | 
| 
      
 679 
     | 
    
         
            +
            	// will potentially oversleep by the amount of time the iteration
         
     | 
| 
      
 680 
     | 
    
         
            +
            	// took to execute.
         
     | 
| 
       676 
681 
     | 
    
         
             
            	uint64_t next_event = 0;
         
     | 
| 
      
 682 
     | 
    
         
            +
            	uint64_t current_time = GetRealTime();
         
     | 
| 
       677 
683 
     | 
    
         | 
| 
       678 
684 
     | 
    
         
             
            	if (!Heartbeats.empty()) {
         
     | 
| 
       679 
685 
     | 
    
         
             
            		multimap<uint64_t,EventableDescriptor*>::iterator heartbeats = Heartbeats.begin();
         
     | 
| 
         @@ -687,16 +693,16 @@ timeval EventMachine_t::_TimeTilNextEvent() 
     | 
|
| 
       687 
693 
     | 
    
         
             
            	}
         
     | 
| 
       688 
694 
     | 
    
         | 
| 
       689 
695 
     | 
    
         
             
            	if (!NewDescriptors.empty() || !ModifiedDescriptors.empty()) {
         
     | 
| 
       690 
     | 
    
         
            -
            		next_event =  
     | 
| 
      
 696 
     | 
    
         
            +
            		next_event = current_time;
         
     | 
| 
       691 
697 
     | 
    
         
             
            	}
         
     | 
| 
       692 
     | 
    
         
            -
             
     | 
| 
      
 698 
     | 
    
         
            +
            	
         
     | 
| 
       693 
699 
     | 
    
         
             
            	timeval tv;
         
     | 
| 
       694 
700 
     | 
    
         | 
| 
       695 
     | 
    
         
            -
            	if (next_event == 0) {
         
     | 
| 
      
 701 
     | 
    
         
            +
            	if (next_event == 0 || NumCloseScheduled > 0) {
         
     | 
| 
       696 
702 
     | 
    
         
             
            		tv = Quantum;
         
     | 
| 
       697 
703 
     | 
    
         
             
            	} else {
         
     | 
| 
       698 
     | 
    
         
            -
            		if (next_event >  
     | 
| 
       699 
     | 
    
         
            -
            			uint64_t duration = next_event -  
     | 
| 
      
 704 
     | 
    
         
            +
            		if (next_event > current_time) {
         
     | 
| 
      
 705 
     | 
    
         
            +
            			uint64_t duration = next_event - current_time;
         
     | 
| 
       700 
706 
     | 
    
         
             
            			tv.tv_sec = duration / 1000000;
         
     | 
| 
       701 
707 
     | 
    
         
             
            			tv.tv_usec = duration % 1000000;
         
     | 
| 
       702 
708 
     | 
    
         
             
            		} else {
         
     | 
| 
         @@ -1356,6 +1362,7 @@ const unsigned long EventMachine_t::AttachFD (int fd, bool watch_mode) 
     | 
|
| 
       1356 
1362 
     | 
    
         
             
            	if (!cd)
         
     | 
| 
       1357 
1363 
     | 
    
         
             
            		throw std::runtime_error ("no connection allocated");
         
     | 
| 
       1358 
1364 
     | 
    
         | 
| 
      
 1365 
     | 
    
         
            +
            	cd->SetAttached(true);
         
     | 
| 
       1359 
1366 
     | 
    
         
             
            	cd->SetWatchOnly(watch_mode);
         
     | 
| 
       1360 
1367 
     | 
    
         
             
            	cd->SetConnectPending (false);
         
     | 
| 
       1361 
1368 
     | 
    
         | 
| 
         @@ -1395,7 +1402,11 @@ int EventMachine_t::DetachFD (EventableDescriptor *ed) 
     | 
|
| 
       1395 
1402 
     | 
    
         
             
            	if (bKqueue) {
         
     | 
| 
       1396 
1403 
     | 
    
         
             
            		// remove any read/write events for this fd
         
     | 
| 
       1397 
1404 
     | 
    
         
             
            		struct kevent k;
         
     | 
| 
      
 1405 
     | 
    
         
            +
            #ifdef __NetBSD__
         
     | 
| 
      
 1406 
     | 
    
         
            +
            		EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, (intptr_t)ed);
         
     | 
| 
      
 1407 
     | 
    
         
            +
            #else
         
     | 
| 
       1398 
1408 
     | 
    
         
             
            		EV_SET (&k, ed->GetSocket(), EVFILT_READ | EVFILT_WRITE, EV_DELETE, 0, 0, ed);
         
     | 
| 
      
 1409 
     | 
    
         
            +
            #endif
         
     | 
| 
       1399 
1410 
     | 
    
         
             
            		int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
         
     | 
| 
       1400 
1411 
     | 
    
         
             
            		if (t < 0 && (errno != ENOENT) && (errno != EBADF)) {
         
     | 
| 
       1401 
1412 
     | 
    
         
             
            			char buf [200];
         
     | 
| 
         @@ -1651,7 +1662,11 @@ void EventMachine_t::ArmKqueueWriter (EventableDescriptor *ed) 
     | 
|
| 
       1651 
1662 
     | 
    
         
             
            		if (!ed)
         
     | 
| 
       1652 
1663 
     | 
    
         
             
            			throw std::runtime_error ("added bad descriptor");
         
     | 
| 
       1653 
1664 
     | 
    
         
             
            		struct kevent k;
         
     | 
| 
      
 1665 
     | 
    
         
            +
            #ifdef __NetBSD__
         
     | 
| 
      
 1666 
     | 
    
         
            +
            		EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, (intptr_t)ed);
         
     | 
| 
      
 1667 
     | 
    
         
            +
            #else
         
     | 
| 
       1654 
1668 
     | 
    
         
             
            		EV_SET (&k, ed->GetSocket(), EVFILT_WRITE, EV_ADD | EV_ONESHOT, 0, 0, ed);
         
     | 
| 
      
 1669 
     | 
    
         
            +
            #endif
         
     | 
| 
       1655 
1670 
     | 
    
         
             
            		int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
         
     | 
| 
       1656 
1671 
     | 
    
         
             
            		if (t < 0) {
         
     | 
| 
       1657 
1672 
     | 
    
         
             
            			char buf [200];
         
     | 
| 
         @@ -1673,7 +1688,11 @@ void EventMachine_t::ArmKqueueReader (EventableDescriptor *ed) 
     | 
|
| 
       1673 
1688 
     | 
    
         
             
            		if (!ed)
         
     | 
| 
       1674 
1689 
     | 
    
         
             
            			throw std::runtime_error ("added bad descriptor");
         
     | 
| 
       1675 
1690 
     | 
    
         
             
            		struct kevent k;
         
     | 
| 
      
 1691 
     | 
    
         
            +
            #ifdef __NetBSD__
         
     | 
| 
      
 1692 
     | 
    
         
            +
            		EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed);
         
     | 
| 
      
 1693 
     | 
    
         
            +
            #else
         
     | 
| 
       1676 
1694 
     | 
    
         
             
            		EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed);
         
     | 
| 
      
 1695 
     | 
    
         
            +
            #endif
         
     | 
| 
       1677 
1696 
     | 
    
         
             
            		int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
         
     | 
| 
       1678 
1697 
     | 
    
         
             
            		if (t < 0) {
         
     | 
| 
       1679 
1698 
     | 
    
         
             
            			char buf [200];
         
     | 
| 
         @@ -1724,7 +1743,11 @@ void EventMachine_t::_AddNewDescriptors() 
     | 
|
| 
       1724 
1743 
     | 
    
         
             
            			// INCOMPLETE. Some descriptors don't want to be readable.
         
     | 
| 
       1725 
1744 
     | 
    
         
             
            			assert (kqfd != -1);
         
     | 
| 
       1726 
1745 
     | 
    
         
             
            			struct kevent k;
         
     | 
| 
      
 1746 
     | 
    
         
            +
            #ifdef __NetBSD__
         
     | 
| 
      
 1747 
     | 
    
         
            +
            			EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, (intptr_t)ed);
         
     | 
| 
      
 1748 
     | 
    
         
            +
            #else
         
     | 
| 
       1727 
1749 
     | 
    
         
             
            			EV_SET (&k, ed->GetSocket(), EVFILT_READ, EV_ADD, 0, 0, ed);
         
     | 
| 
      
 1750 
     | 
    
         
            +
            #endif
         
     | 
| 
       1728 
1751 
     | 
    
         
             
            			int t = kevent (kqfd, &k, 1, NULL, 0, NULL);
         
     | 
| 
       1729 
1752 
     | 
    
         
             
            			assert (t == 0);
         
     | 
| 
       1730 
1753 
     | 
    
         
             
            		}
         
     | 
    
        data/ext/em.h
    CHANGED
    
    | 
         @@ -44,10 +44,10 @@ See the file COPYING for complete licensing information. 
     | 
|
| 
       44 
44 
     | 
    
         
             
                #define RUBY_UBF_IO RB_UBF_DFL
         
     | 
| 
       45 
45 
     | 
    
         
             
              #endif
         
     | 
| 
       46 
46 
     | 
    
         
             
              #ifndef RSTRING_PTR
         
     | 
| 
       47 
     | 
    
         
            -
                #define RSTRING_PTR(str)  
     | 
| 
      
 47 
     | 
    
         
            +
                #define RSTRING_PTR(str) RSTRING(str)->ptr
         
     | 
| 
       48 
48 
     | 
    
         
             
              #endif
         
     | 
| 
       49 
49 
     | 
    
         
             
              #ifndef RSTRING_LEN
         
     | 
| 
       50 
     | 
    
         
            -
                #define RSTRING_LEN(str)  
     | 
| 
      
 50 
     | 
    
         
            +
                #define RSTRING_LEN(str) RSTRING(str)->len
         
     | 
| 
       51 
51 
     | 
    
         
             
              #endif
         
     | 
| 
       52 
52 
     | 
    
         
             
              #ifndef RSTRING_LENINT
         
     | 
| 
       53 
53 
     | 
    
         
             
                #define RSTRING_LENINT(str) RSTRING_LEN(str)
         
     | 
| 
         @@ -161,6 +161,7 @@ class EventMachine_t 
     | 
|
| 
       161 
161 
     | 
    
         
             
            	public:
         
     | 
| 
       162 
162 
     | 
    
         
             
            		void _ReadLoopBreaker();
         
     | 
| 
       163 
163 
     | 
    
         
             
            		void _ReadInotifyEvents();
         
     | 
| 
      
 164 
     | 
    
         
            +
                    int NumCloseScheduled;
         
     | 
| 
       164 
165 
     | 
    
         | 
| 
       165 
166 
     | 
    
         
             
            	private:
         
     | 
| 
       166 
167 
     | 
    
         
             
            		enum {
         
     | 
    
        data/ext/eventmachine.h
    CHANGED
    
    | 
         @@ -59,6 +59,8 @@ extern "C" { 
     | 
|
| 
       59 
59 
     | 
    
         
             
            	int evma_is_paused(const unsigned long binding);
         
     | 
| 
       60 
60 
     | 
    
         
             
            	int evma_resume(const unsigned long binding);
         
     | 
| 
       61 
61 
     | 
    
         | 
| 
      
 62 
     | 
    
         
            +
                int evma_num_close_scheduled();
         
     | 
| 
      
 63 
     | 
    
         
            +
             
     | 
| 
       62 
64 
     | 
    
         
             
            	void evma_stop_tcp_server (const unsigned long signature);
         
     | 
| 
       63 
65 
     | 
    
         
             
            	const unsigned long evma_create_tcp_server (const char *address, int port);
         
     | 
| 
       64 
66 
     | 
    
         
             
            	const unsigned long evma_create_unix_domain_server (const char *filename);
         
     | 
| 
         @@ -84,6 +86,7 @@ extern "C" { 
     | 
|
| 
       84 
86 
     | 
    
         
             
            	float evma_get_pending_connect_timeout (const unsigned long binding);
         
     | 
| 
       85 
87 
     | 
    
         
             
            	int evma_set_pending_connect_timeout (const unsigned long binding, float value);
         
     | 
| 
       86 
88 
     | 
    
         
             
            	int evma_get_outbound_data_size (const unsigned long binding);
         
     | 
| 
      
 89 
     | 
    
         
            +
            	uint64_t evma_get_last_activity_time (const unsigned long);
         
     | 
| 
       87 
90 
     | 
    
         
             
            	int evma_send_file_data_to_connection (const unsigned long binding, const char *filename);
         
     | 
| 
       88 
91 
     | 
    
         | 
| 
       89 
92 
     | 
    
         
             
            	void evma_close_connection (const unsigned long binding, int after_writing);
         
     | 
| 
         @@ -107,6 +110,7 @@ extern "C" { 
     | 
|
| 
       107 
110 
     | 
    
         | 
| 
       108 
111 
     | 
    
         
             
            	void evma_start_proxy(const unsigned long, const unsigned long, const unsigned long, const unsigned long);
         
     | 
| 
       109 
112 
     | 
    
         
             
            	void evma_stop_proxy(const unsigned long);
         
     | 
| 
      
 113 
     | 
    
         
            +
            	unsigned long evma_proxied_bytes(const unsigned long);
         
     | 
| 
       110 
114 
     | 
    
         | 
| 
       111 
115 
     | 
    
         
             
            	int evma_set_rlimit_nofile (int n_files);
         
     | 
| 
       112 
116 
     | 
    
         | 
    
        data/ext/extconf.rb
    CHANGED
    
    | 
         @@ -92,7 +92,7 @@ end 
     | 
|
| 
       92 
92 
     | 
    
         
             
            case RUBY_PLATFORM
         
     | 
| 
       93 
93 
     | 
    
         
             
            when /mswin32/, /mingw32/, /bccwin32/
         
     | 
| 
       94 
94 
     | 
    
         
             
              check_heads(%w[windows.h winsock.h], true)
         
     | 
| 
       95 
     | 
    
         
            -
              check_libs(%w[kernel32 rpcrt4 gdi32], true) 
     | 
| 
      
 95 
     | 
    
         
            +
              check_libs(%w[kernel32 rpcrt4 gdi32], true)
         
     | 
| 
       96 
96 
     | 
    
         | 
| 
       97 
97 
     | 
    
         
             
              if GNU_CHAIN
         
     | 
| 
       98 
98 
     | 
    
         
             
                CONFIG['LDSHARED'] = "$(CXX) -shared -lstdc++"
         
     | 
| 
         @@ -139,6 +139,15 @@ when /linux/ 
     | 
|
| 
       139 
139 
     | 
    
         
             
            when /aix/
         
     | 
| 
       140 
140 
     | 
    
         
             
              CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G -Wl,-brtl"
         
     | 
| 
       141 
141 
     | 
    
         | 
| 
      
 142 
     | 
    
         
            +
            when /cygwin/
         
     | 
| 
      
 143 
     | 
    
         
            +
              # For rubies built with Cygwin, CXX may be set to CC, which is just
         
     | 
| 
      
 144 
     | 
    
         
            +
              # a wrapper for gcc.
         
     | 
| 
      
 145 
     | 
    
         
            +
              # This will compile, but it will not link to the C++ std library.
         
     | 
| 
      
 146 
     | 
    
         
            +
              # Explicitly set CXX to use g++.
         
     | 
| 
      
 147 
     | 
    
         
            +
              CONFIG['CXX'] = "g++"
         
     | 
| 
      
 148 
     | 
    
         
            +
              # on Unix we need a g++ link, not gcc.
         
     | 
| 
      
 149 
     | 
    
         
            +
              CONFIG['LDSHARED'] = "$(CXX) -shared"
         
     | 
| 
      
 150 
     | 
    
         
            +
             
     | 
| 
       142 
151 
     | 
    
         
             
            else
         
     | 
| 
       143 
152 
     | 
    
         
             
              # on Unix we need a g++ link, not gcc.
         
     | 
| 
       144 
153 
     | 
    
         
             
              CONFIG['LDSHARED'] = "$(CXX) -shared"
         
     | 
| 
         @@ -154,4 +163,4 @@ add_define 'HAVE_MAKE_PAIR' if try_link(<<SRC, '-lstdc++') 
     | 
|
| 
       154 
163 
     | 
    
         
             
            SRC
         
     | 
| 
       155 
164 
     | 
    
         
             
            TRY_LINK.sub!('$(CXX)', '$(CC)')
         
     | 
| 
       156 
165 
     | 
    
         | 
| 
       157 
     | 
    
         
            -
            create_makefile "rubyeventmachine"
         
     | 
| 
      
 166 
     | 
    
         
            +
            create_makefile "rubyeventmachine"
         
     | 
| 
         @@ -77,9 +77,18 @@ when /aix/ 
     | 
|
| 
       77 
77 
     | 
    
         
             
              # on Unix we need a g++ link, not gcc.
         
     | 
| 
       78 
78 
     | 
    
         
             
              CONFIG['LDSHARED'] = "$(CXX) -shared -Wl,-G"
         
     | 
| 
       79 
79 
     | 
    
         | 
| 
      
 80 
     | 
    
         
            +
            when /cygwin/
         
     | 
| 
      
 81 
     | 
    
         
            +
              # For rubies built with Cygwin, CXX may be set to CC, which is just
         
     | 
| 
      
 82 
     | 
    
         
            +
              # a wrapper for gcc.
         
     | 
| 
      
 83 
     | 
    
         
            +
              # This will compile, but it will not link to the C++ std library.
         
     | 
| 
      
 84 
     | 
    
         
            +
              # Explicitly set CXX to use g++.
         
     | 
| 
      
 85 
     | 
    
         
            +
              CONFIG['CXX'] = "g++"
         
     | 
| 
      
 86 
     | 
    
         
            +
              # on Unix we need a g++ link, not gcc.
         
     | 
| 
      
 87 
     | 
    
         
            +
              CONFIG['LDSHARED'] = "$(CXX) -shared"
         
     | 
| 
      
 88 
     | 
    
         
            +
             
     | 
| 
       80 
89 
     | 
    
         
             
            else
         
     | 
| 
       81 
90 
     | 
    
         
             
              # on Unix we need a g++ link, not gcc.
         
     | 
| 
       82 
91 
     | 
    
         
             
              CONFIG['LDSHARED'] = "$(CXX) -shared"
         
     | 
| 
       83 
92 
     | 
    
         
             
            end
         
     | 
| 
       84 
93 
     | 
    
         | 
| 
       85 
     | 
    
         
            -
            create_makefile "fastfilereaderext"
         
     | 
| 
      
 94 
     | 
    
         
            +
            create_makefile "fastfilereaderext"
         
     | 
    
        data/ext/project.h
    CHANGED
    
    | 
         @@ -82,7 +82,8 @@ typedef int SOCKET; 
     | 
|
| 
       82 
82 
     | 
    
         | 
| 
       83 
83 
     | 
    
         
             
            #ifdef OS_WIN32
         
     | 
| 
       84 
84 
     | 
    
         
             
            // 21Sep09: windows limits select() to 64 sockets by default, we increase it to 1024 here (before including winsock2.h)
         
     | 
| 
       85 
     | 
    
         
            -
             
     | 
| 
      
 85 
     | 
    
         
            +
            // 18Jun12: fd_setsize must be changed in the ruby binary (not in this extension). redefining it also causes segvs, see eventmachine/eventmachine#333
         
     | 
| 
      
 86 
     | 
    
         
            +
            //#define FD_SETSIZE 1024
         
     | 
| 
       86 
87 
     | 
    
         | 
| 
       87 
88 
     | 
    
         
             
            #define WIN32_LEAN_AND_MEAN
         
     | 
| 
       88 
89 
     | 
    
         
             
            #include <windows.h>
         
     | 
    
        data/ext/rubymain.cpp
    CHANGED
    
    | 
         @@ -507,7 +507,7 @@ static VALUE t_connect_server (VALUE self, VALUE server, VALUE port) 
     | 
|
| 
       507 
507 
     | 
    
         
             
            			rb_raise (EM_eConnectionError, "no connection");
         
     | 
| 
       508 
508 
     | 
    
         
             
            		return ULONG2NUM (f);
         
     | 
| 
       509 
509 
     | 
    
         
             
            	} catch (std::runtime_error e) {
         
     | 
| 
       510 
     | 
    
         
            -
            		rb_raise (EM_eConnectionError, e.what());
         
     | 
| 
      
 510 
     | 
    
         
            +
            		rb_raise (EM_eConnectionError, "%s", e.what());
         
     | 
| 
       511 
511 
     | 
    
         
             
            	}
         
     | 
| 
       512 
512 
     | 
    
         
             
            	return Qnil;
         
     | 
| 
       513 
513 
     | 
    
         
             
            }
         
     | 
| 
         @@ -528,7 +528,7 @@ static VALUE t_bind_connect_server (VALUE self, VALUE bind_addr, VALUE bind_port 
     | 
|
| 
       528 
528 
     | 
    
         
             
            			rb_raise (EM_eConnectionError, "no connection");
         
     | 
| 
       529 
529 
     | 
    
         
             
            		return ULONG2NUM (f);
         
     | 
| 
       530 
530 
     | 
    
         
             
            	} catch (std::runtime_error e) {
         
     | 
| 
       531 
     | 
    
         
            -
            		rb_raise (EM_eConnectionError, e.what());
         
     | 
| 
      
 531 
     | 
    
         
            +
            		rb_raise (EM_eConnectionError, "%s", e.what());
         
     | 
| 
       532 
532 
     | 
    
         
             
            	}
         
     | 
| 
       533 
533 
     | 
    
         
             
            	return Qnil;
         
     | 
| 
       534 
534 
     | 
    
         
             
            }
         
     | 
| 
         @@ -686,6 +686,15 @@ static VALUE t_paused_p (VALUE self, VALUE signature) 
     | 
|
| 
       686 
686 
     | 
    
         
             
            	return evma_is_paused(NUM2ULONG (signature)) ? Qtrue : Qfalse;
         
     | 
| 
       687 
687 
     | 
    
         
             
            }
         
     | 
| 
       688 
688 
     | 
    
         | 
| 
      
 689 
     | 
    
         
            +
            /*********************
         
     | 
| 
      
 690 
     | 
    
         
            +
            t_num_close_scheduled
         
     | 
| 
      
 691 
     | 
    
         
            +
            *********************/
         
     | 
| 
      
 692 
     | 
    
         
            +
             
     | 
| 
      
 693 
     | 
    
         
            +
            static VALUE t_num_close_scheduled (VALUE self)
         
     | 
| 
      
 694 
     | 
    
         
            +
            {
         
     | 
| 
      
 695 
     | 
    
         
            +
            	return INT2FIX(evma_num_close_scheduled());
         
     | 
| 
      
 696 
     | 
    
         
            +
            }
         
     | 
| 
      
 697 
     | 
    
         
            +
             
     | 
| 
       689 
698 
     | 
    
         
             
            /*****************
         
     | 
| 
       690 
699 
     | 
    
         
             
            t_open_udp_socket
         
     | 
| 
       691 
700 
     | 
    
         
             
            *****************/
         
     | 
| 
         @@ -839,7 +848,7 @@ static VALUE t_watch_filename (VALUE self, VALUE fname) 
     | 
|
| 
       839 
848 
     | 
    
         
             
            	try {
         
     | 
| 
       840 
849 
     | 
    
         
             
            		return ULONG2NUM(evma_watch_filename(StringValuePtr(fname)));
         
     | 
| 
       841 
850 
     | 
    
         
             
            	} catch (std::runtime_error e) {
         
     | 
| 
       842 
     | 
    
         
            -
            		rb_raise (EM_eUnsupported, e.what());
         
     | 
| 
      
 851 
     | 
    
         
            +
            		rb_raise (EM_eUnsupported, "%s", e.what());
         
     | 
| 
       843 
852 
     | 
    
         
             
            	}
         
     | 
| 
       844 
853 
     | 
    
         
             
            	return Qnil;
         
     | 
| 
       845 
854 
     | 
    
         
             
            }
         
     | 
| 
         @@ -865,7 +874,7 @@ static VALUE t_watch_pid (VALUE self, VALUE pid) 
     | 
|
| 
       865 
874 
     | 
    
         
             
            	try {
         
     | 
| 
       866 
875 
     | 
    
         
             
            		return ULONG2NUM(evma_watch_pid(NUM2INT(pid)));
         
     | 
| 
       867 
876 
     | 
    
         
             
            	} catch (std::runtime_error e) {
         
     | 
| 
       868 
     | 
    
         
            -
            		rb_raise (EM_eUnsupported, e.what());
         
     | 
| 
      
 877 
     | 
    
         
            +
            		rb_raise (EM_eUnsupported, "%s", e.what());
         
     | 
| 
       869 
878 
     | 
    
         
             
            	}
         
     | 
| 
       870 
879 
     | 
    
         
             
            	return Qnil;
         
     | 
| 
       871 
880 
     | 
    
         
             
            }
         
     | 
| 
         @@ -1065,7 +1074,7 @@ static VALUE t_start_proxy (VALUE self, VALUE from, VALUE to, VALUE bufsize, VAL 
     | 
|
| 
       1065 
1074 
     | 
    
         
             
            	try {
         
     | 
| 
       1066 
1075 
     | 
    
         
             
            		evma_start_proxy(NUM2ULONG (from), NUM2ULONG (to), NUM2ULONG(bufsize), NUM2ULONG(length));
         
     | 
| 
       1067 
1076 
     | 
    
         
             
            	} catch (std::runtime_error e) {
         
     | 
| 
       1068 
     | 
    
         
            -
            		rb_raise (EM_eConnectionError, e.what());
         
     | 
| 
      
 1077 
     | 
    
         
            +
            		rb_raise (EM_eConnectionError, "%s", e.what());
         
     | 
| 
       1069 
1078 
     | 
    
         
             
            	}
         
     | 
| 
       1070 
1079 
     | 
    
         
             
            	return Qnil;
         
     | 
| 
       1071 
1080 
     | 
    
         
             
            }
         
     | 
| 
         @@ -1080,11 +1089,49 @@ static VALUE t_stop_proxy (VALUE self, VALUE from) 
     | 
|
| 
       1080 
1089 
     | 
    
         
             
            	try{
         
     | 
| 
       1081 
1090 
     | 
    
         
             
            		evma_stop_proxy(NUM2ULONG (from));
         
     | 
| 
       1082 
1091 
     | 
    
         
             
            	} catch (std::runtime_error e) {
         
     | 
| 
       1083 
     | 
    
         
            -
            		rb_raise (EM_eConnectionError, e.what());
         
     | 
| 
      
 1092 
     | 
    
         
            +
            		rb_raise (EM_eConnectionError, "%s", e.what());
         
     | 
| 
       1084 
1093 
     | 
    
         
             
            	}
         
     | 
| 
       1085 
1094 
     | 
    
         
             
            	return Qnil;
         
     | 
| 
       1086 
1095 
     | 
    
         
             
            }
         
     | 
| 
       1087 
1096 
     | 
    
         | 
| 
      
 1097 
     | 
    
         
            +
            /***************
         
     | 
| 
      
 1098 
     | 
    
         
            +
            t_proxied_bytes
         
     | 
| 
      
 1099 
     | 
    
         
            +
            ****************/
         
     | 
| 
      
 1100 
     | 
    
         
            +
             
     | 
| 
      
 1101 
     | 
    
         
            +
            static VALUE t_proxied_bytes (VALUE self, VALUE from)
         
     | 
| 
      
 1102 
     | 
    
         
            +
            {
         
     | 
| 
      
 1103 
     | 
    
         
            +
            	try{
         
     | 
| 
      
 1104 
     | 
    
         
            +
            		return ULONG2NUM(evma_proxied_bytes(NUM2ULONG (from)));
         
     | 
| 
      
 1105 
     | 
    
         
            +
            	} catch (std::runtime_error e) {
         
     | 
| 
      
 1106 
     | 
    
         
            +
            		rb_raise (EM_eConnectionError, "%s", e.what());
         
     | 
| 
      
 1107 
     | 
    
         
            +
            	}
         
     | 
| 
      
 1108 
     | 
    
         
            +
            	return Qnil;
         
     | 
| 
      
 1109 
     | 
    
         
            +
            }
         
     | 
| 
      
 1110 
     | 
    
         
            +
             
     | 
| 
      
 1111 
     | 
    
         
            +
            /***************
         
     | 
| 
      
 1112 
     | 
    
         
            +
            t_get_idle_time
         
     | 
| 
      
 1113 
     | 
    
         
            +
            ****************/
         
     | 
| 
      
 1114 
     | 
    
         
            +
             
     | 
| 
      
 1115 
     | 
    
         
            +
            static VALUE t_get_idle_time (VALUE self, VALUE from)
         
     | 
| 
      
 1116 
     | 
    
         
            +
            {
         
     | 
| 
      
 1117 
     | 
    
         
            +
            	try{
         
     | 
| 
      
 1118 
     | 
    
         
            +
            		uint64_t current_time = evma_get_current_loop_time();
         
     | 
| 
      
 1119 
     | 
    
         
            +
            		uint64_t time = evma_get_last_activity_time(NUM2ULONG (from));
         
     | 
| 
      
 1120 
     | 
    
         
            +
            		if (current_time != 0 && time != 0) {
         
     | 
| 
      
 1121 
     | 
    
         
            +
            			if (time >= current_time)
         
     | 
| 
      
 1122 
     | 
    
         
            +
            				return ULONG2NUM(0);
         
     | 
| 
      
 1123 
     | 
    
         
            +
            			else {
         
     | 
| 
      
 1124 
     | 
    
         
            +
            				uint64_t diff = current_time - time;
         
     | 
| 
      
 1125 
     | 
    
         
            +
            				float seconds = diff / (1000.0*1000.0);
         
     | 
| 
      
 1126 
     | 
    
         
            +
            				return rb_float_new(seconds);
         
     | 
| 
      
 1127 
     | 
    
         
            +
            			}
         
     | 
| 
      
 1128 
     | 
    
         
            +
            			return Qnil;
         
     | 
| 
      
 1129 
     | 
    
         
            +
            		}
         
     | 
| 
      
 1130 
     | 
    
         
            +
            	} catch (std::runtime_error e) {
         
     | 
| 
      
 1131 
     | 
    
         
            +
            		rb_raise (EM_eConnectionError, "%s", e.what());
         
     | 
| 
      
 1132 
     | 
    
         
            +
            	}
         
     | 
| 
      
 1133 
     | 
    
         
            +
            	return Qnil;
         
     | 
| 
      
 1134 
     | 
    
         
            +
            }
         
     | 
| 
       1088 
1135 
     | 
    
         | 
| 
       1089 
1136 
     | 
    
         
             
            /************************
         
     | 
| 
       1090 
1137 
     | 
    
         
             
            t_get_heartbeat_interval
         
     | 
| 
         @@ -1180,9 +1227,11 @@ extern "C" void Init_rubyeventmachine() 
     | 
|
| 
       1180 
1227 
     | 
    
         
             
            	rb_define_module_function (EmModule, "pause_connection", (VALUE (*)(...))t_pause, 1);
         
     | 
| 
       1181 
1228 
     | 
    
         
             
            	rb_define_module_function (EmModule, "resume_connection", (VALUE (*)(...))t_resume, 1);
         
     | 
| 
       1182 
1229 
     | 
    
         
             
            	rb_define_module_function (EmModule, "connection_paused?", (VALUE (*)(...))t_paused_p, 1);
         
     | 
| 
      
 1230 
     | 
    
         
            +
            	rb_define_module_function (EmModule, "num_close_scheduled", (VALUE (*)(...))t_num_close_scheduled, 0);
         
     | 
| 
       1183 
1231 
     | 
    
         | 
| 
       1184 
1232 
     | 
    
         
             
            	rb_define_module_function (EmModule, "start_proxy", (VALUE (*)(...))t_start_proxy, 4);
         
     | 
| 
       1185 
1233 
     | 
    
         
             
            	rb_define_module_function (EmModule, "stop_proxy", (VALUE (*)(...))t_stop_proxy, 1);
         
     | 
| 
      
 1234 
     | 
    
         
            +
            	rb_define_module_function (EmModule, "get_proxied_bytes", (VALUE (*)(...))t_proxied_bytes, 1);
         
     | 
| 
       1186 
1235 
     | 
    
         | 
| 
       1187 
1236 
     | 
    
         
             
            	rb_define_module_function (EmModule, "watch_filename", (VALUE (*)(...))t_watch_filename, 1);
         
     | 
| 
       1188 
1237 
     | 
    
         
             
            	rb_define_module_function (EmModule, "unwatch_filename", (VALUE (*)(...))t_unwatch_filename, 1);
         
     | 
| 
         @@ -1206,6 +1255,7 @@ extern "C" void Init_rubyeventmachine() 
     | 
|
| 
       1206 
1255 
     | 
    
         
             
            	rb_define_module_function (EmModule, "send_file_data", (VALUE(*)(...))t_send_file_data, 2);
         
     | 
| 
       1207 
1256 
     | 
    
         
             
            	rb_define_module_function (EmModule, "get_heartbeat_interval", (VALUE(*)(...))t_get_heartbeat_interval, 0);
         
     | 
| 
       1208 
1257 
     | 
    
         
             
            	rb_define_module_function (EmModule, "set_heartbeat_interval", (VALUE(*)(...))t_set_heartbeat_interval, 1);
         
     | 
| 
      
 1258 
     | 
    
         
            +
            	rb_define_module_function (EmModule, "get_idle_time", (VALUE(*)(...))t_get_idle_time, 1);
         
     | 
| 
       1209 
1259 
     | 
    
         | 
| 
       1210 
1260 
     | 
    
         
             
            	rb_define_module_function (EmModule, "get_peername", (VALUE(*)(...))t_get_peername, 1);
         
     | 
| 
       1211 
1261 
     | 
    
         
             
            	rb_define_module_function (EmModule, "get_sockname", (VALUE(*)(...))t_get_sockname, 1);
         
     | 
    
        data/ext/ssl.cpp
    CHANGED
    
    | 
         @@ -137,7 +137,7 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str 
     | 
|
| 
       137 
137 
     | 
    
         
             
            		bLibraryInitialized = true;
         
     | 
| 
       138 
138 
     | 
    
         
             
            		SSL_library_init();
         
     | 
| 
       139 
139 
     | 
    
         
             
            		OpenSSL_add_ssl_algorithms();
         
     | 
| 
       140 
     | 
    
         
            -
             
     | 
| 
      
 140 
     | 
    
         
            +
            		OpenSSL_add_all_algorithms();
         
     | 
| 
       141 
141 
     | 
    
         
             
            		SSL_load_error_strings();
         
     | 
| 
       142 
142 
     | 
    
         
             
            		ERR_load_crypto_strings();
         
     | 
| 
       143 
143 
     | 
    
         | 
| 
         @@ -151,6 +151,9 @@ SslContext_t::SslContext_t (bool is_server, const string &privkeyfile, const str 
     | 
|
| 
       151 
151 
     | 
    
         | 
| 
       152 
152 
     | 
    
         
             
            	SSL_CTX_set_options (pCtx, SSL_OP_ALL);
         
     | 
| 
       153 
153 
     | 
    
         
             
            	//SSL_CTX_set_options (pCtx, (SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3));
         
     | 
| 
      
 154 
     | 
    
         
            +
            #ifdef SSL_MODE_RELEASE_BUFFERS
         
     | 
| 
      
 155 
     | 
    
         
            +
            	SSL_CTX_set_mode (pCtx, SSL_MODE_RELEASE_BUFFERS);
         
     | 
| 
      
 156 
     | 
    
         
            +
            #endif
         
     | 
| 
       154 
157 
     | 
    
         | 
| 
       155 
158 
     | 
    
         
             
            	if (is_server) {
         
     | 
| 
       156 
159 
     | 
    
         
             
            		// The SSL_CTX calls here do NOT allocate memory.
         
     | 
| 
         @@ -524,6 +524,10 @@ public class EmReactor { 
     | 
|
| 
       524 
524 
     | 
    
         
             
            		return Connections.get(sig).getPeerName();
         
     | 
| 
       525 
525 
     | 
    
         
             
            	}
         
     | 
| 
       526 
526 
     | 
    
         | 
| 
      
 527 
     | 
    
         
            +
            	public Object[] getSockName (long sig) {
         
     | 
| 
      
 528 
     | 
    
         
            +
            		return Connections.get(sig).getSockName();
         
     | 
| 
      
 529 
     | 
    
         
            +
            	}
         
     | 
| 
      
 530 
     | 
    
         
            +
             
     | 
| 
       527 
531 
     | 
    
         
             
            	public long attachChannel (SocketChannel sc, boolean watch_mode) {
         
     | 
| 
       528 
532 
     | 
    
         
             
            		long b = createBinding();
         
     | 
| 
       529 
533 
     | 
    
         | 
| 
         @@ -183,6 +183,12 @@ public class EventableDatagramChannel implements EventableChannel { 
     | 
|
| 
       183 
183 
     | 
    
         
             
            		}
         
     | 
| 
       184 
184 
     | 
    
         
             
            	}
         
     | 
| 
       185 
185 
     | 
    
         | 
| 
      
 186 
     | 
    
         
            +
            	public Object[] getSockName () {
         
     | 
| 
      
 187 
     | 
    
         
            +
            		DatagramSocket socket = channel.socket();
         
     | 
| 
      
 188 
     | 
    
         
            +
            		return new Object[]{ socket.getLocalPort(),
         
     | 
| 
      
 189 
     | 
    
         
            +
            							 socket.getLocalAddress().getHostAddress() };
         
     | 
| 
      
 190 
     | 
    
         
            +
            	}
         
     | 
| 
      
 191 
     | 
    
         
            +
             
     | 
| 
       186 
192 
     | 
    
         
             
            	public boolean isWatchOnly() { return false; }
         
     | 
| 
       187 
193 
     | 
    
         
             
            	public boolean isNotifyReadable() { return false; }
         
     | 
| 
       188 
194 
     | 
    
         
             
            	public boolean isNotifyWritable() { return false; }
         
     | 
| 
         @@ -302,6 +302,12 @@ public class EventableSocketChannel implements EventableChannel { 
     | 
|
| 
       302 
302 
     | 
    
         
             
            		return new Object[]{ sock.getPort(), sock.getInetAddress().getHostAddress() };
         
     | 
| 
       303 
303 
     | 
    
         
             
            	}
         
     | 
| 
       304 
304 
     | 
    
         | 
| 
      
 305 
     | 
    
         
            +
            	public Object[] getSockName () {
         
     | 
| 
      
 306 
     | 
    
         
            +
            		Socket sock = channel.socket();
         
     | 
| 
      
 307 
     | 
    
         
            +
            		return new Object[]{ sock.getLocalPort(),
         
     | 
| 
      
 308 
     | 
    
         
            +
            							 sock.getLocalAddress().getHostAddress() };
         
     | 
| 
      
 309 
     | 
    
         
            +
            	}
         
     | 
| 
      
 310 
     | 
    
         
            +
             
     | 
| 
       305 
311 
     | 
    
         
             
            	public void setWatchOnly() {
         
     | 
| 
       306 
312 
     | 
    
         
             
            		bWatchOnly = true;
         
     | 
| 
       307 
313 
     | 
    
         
             
            		updateEvents();
         
     | 
    
        data/lib/em/connection.rb
    CHANGED
    
    | 
         @@ -238,6 +238,12 @@ module EventMachine 
     | 
|
| 
       238 
238 
     | 
    
         
             
                  EventMachine::disable_proxy(self)
         
     | 
| 
       239 
239 
     | 
    
         
             
                end
         
     | 
| 
       240 
240 
     | 
    
         | 
| 
      
 241 
     | 
    
         
            +
                # The number of bytes proxied to another connection. Reset to zero when
         
     | 
| 
      
 242 
     | 
    
         
            +
                # EventMachine::Connection#proxy_incoming_to is called, and incremented whenever data is proxied.
         
     | 
| 
      
 243 
     | 
    
         
            +
                def get_proxied_bytes
         
     | 
| 
      
 244 
     | 
    
         
            +
                  EventMachine::get_proxied_bytes(@signature)
         
     | 
| 
      
 245 
     | 
    
         
            +
                end
         
     | 
| 
      
 246 
     | 
    
         
            +
             
     | 
| 
       241 
247 
     | 
    
         
             
                # EventMachine::Connection#close_connection is called only by user code, and never
         
     | 
| 
       242 
248 
     | 
    
         
             
                # by the event loop. You may call this method against a connection object in any
         
     | 
| 
       243 
249 
     | 
    
         
             
                # callback handler, whether or not the callback was made against the connection
         
     | 
| 
         @@ -570,6 +576,11 @@ module EventMachine 
     | 
|
| 
       570 
576 
     | 
    
         
             
                  EventMachine::get_subprocess_status @signature
         
     | 
| 
       571 
577 
     | 
    
         
             
                end
         
     | 
| 
       572 
578 
     | 
    
         | 
| 
      
 579 
     | 
    
         
            +
                # The number of seconds since the last send/receive activity on this connection.
         
     | 
| 
      
 580 
     | 
    
         
            +
                def get_idle_time
         
     | 
| 
      
 581 
     | 
    
         
            +
                  EventMachine::get_idle_time @signature
         
     | 
| 
      
 582 
     | 
    
         
            +
                end
         
     | 
| 
      
 583 
     | 
    
         
            +
             
     | 
| 
       573 
584 
     | 
    
         
             
                # comm_inactivity_timeout returns the current value (float in seconds) of the inactivity-timeout
         
     | 
| 
       574 
585 
     | 
    
         
             
                # property of network-connection and datagram-socket objects. A nonzero value
         
     | 
| 
       575 
586 
     | 
    
         
             
                # indicates that the connection or socket will automatically be closed if no read or write
         
     | 
    
        data/lib/em/pool.rb
    CHANGED
    
    | 
         @@ -122,7 +122,10 @@ module EventMachine 
     | 
|
| 
       122 
122 
     | 
    
         | 
| 
       123 
123 
     | 
    
         
             
                def failure resource
         
     | 
| 
       124 
124 
     | 
    
         
             
                  if @on_error
         
     | 
| 
      
 125 
     | 
    
         
            +
                    @contents.delete resource
         
     | 
| 
       125 
126 
     | 
    
         
             
                    @on_error.call resource
         
     | 
| 
      
 127 
     | 
    
         
            +
                    # Prevent users from calling a leak.
         
     | 
| 
      
 128 
     | 
    
         
            +
                    @removed.delete resource
         
     | 
| 
       126 
129 
     | 
    
         
             
                  else
         
     | 
| 
       127 
130 
     | 
    
         
             
                    requeue resource
         
     | 
| 
       128 
131 
     | 
    
         
             
                  end
         
     | 
| 
         @@ -140,7 +143,9 @@ module EventMachine 
     | 
|
| 
       140 
143 
     | 
    
         
             
                  else
         
     | 
| 
       141 
144 
     | 
    
         
             
                    raise ArgumentError, "deferrable expected from work"
         
     | 
| 
       142 
145 
     | 
    
         
             
                  end
         
     | 
| 
      
 146 
     | 
    
         
            +
                rescue Exception
         
     | 
| 
      
 147 
     | 
    
         
            +
                  failure resource
         
     | 
| 
      
 148 
     | 
    
         
            +
                  raise
         
     | 
| 
       143 
149 
     | 
    
         
             
                end
         
     | 
| 
       144 
     | 
    
         
            -
             
     | 
| 
       145 
150 
     | 
    
         
             
              end
         
     | 
| 
       146 
     | 
    
         
            -
            end
         
     | 
| 
      
 151 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -31,38 +31,38 @@ module EventMachine 
     | 
|
| 
       31 
31 
     | 
    
         
             
                # Simple SMTP client
         
     | 
| 
       32 
32 
     | 
    
         
             
                #
         
     | 
| 
       33 
33 
     | 
    
         
             
                # @example
         
     | 
| 
       34 
     | 
    
         
            -
                # 
     | 
| 
       35 
     | 
    
         
            -
                # 
     | 
| 
       36 
     | 
    
         
            -
                # 
     | 
| 
       37 
     | 
    
         
            -
                # 
     | 
| 
       38 
     | 
    
         
            -
                # 
     | 
| 
       39 
     | 
    
         
            -
                # 
     | 
| 
       40 
     | 
    
         
            -
                # 
     | 
| 
       41 
     | 
    
         
            -
                # 
     | 
| 
       42 
     | 
    
         
            -
                # 
     | 
| 
       43 
     | 
    
         
            -
                # 
     | 
| 
       44 
     | 
    
         
            -
                # 
     | 
| 
       45 
     | 
    
         
            -
                # 
     | 
| 
       46 
     | 
    
         
            -
                # 
     | 
| 
       47 
     | 
    
         
            -
                # 
     | 
| 
       48 
     | 
    
         
            -
                # 
     | 
| 
       49 
     | 
    
         
            -
                # 
     | 
| 
      
 34 
     | 
    
         
            +
                #   email = EM::Protocols::SmtpClient.send(
         
     | 
| 
      
 35 
     | 
    
         
            +
                #     :domain=>"example.com",
         
     | 
| 
      
 36 
     | 
    
         
            +
                #     :host=>'localhost',
         
     | 
| 
      
 37 
     | 
    
         
            +
                #     :port=>25, # optional, defaults 25
         
     | 
| 
      
 38 
     | 
    
         
            +
                #     :starttls=>true, # use ssl
         
     | 
| 
      
 39 
     | 
    
         
            +
                #     :from=>"sender@example.com",
         
     | 
| 
      
 40 
     | 
    
         
            +
                #     :to=> ["to_1@example.com", "to_2@example.com"],
         
     | 
| 
      
 41 
     | 
    
         
            +
                #     :header=> {"Subject" => "This is a subject line"},
         
     | 
| 
      
 42 
     | 
    
         
            +
                #     :body=> "This is the body of the email"
         
     | 
| 
      
 43 
     | 
    
         
            +
                #   )
         
     | 
| 
      
 44 
     | 
    
         
            +
                #   email.callback{
         
     | 
| 
      
 45 
     | 
    
         
            +
                #     puts 'Email sent!'
         
     | 
| 
      
 46 
     | 
    
         
            +
                #   }
         
     | 
| 
      
 47 
     | 
    
         
            +
                #   email.errback{ |e|
         
     | 
| 
      
 48 
     | 
    
         
            +
                #     puts 'Email failed!'
         
     | 
| 
      
 49 
     | 
    
         
            +
                #   }
         
     | 
| 
       50 
50 
     | 
    
         
             
                #
         
     | 
| 
       51 
51 
     | 
    
         
             
                # Sending generated emails (using mailfactory)
         
     | 
| 
       52 
52 
     | 
    
         
             
                #
         
     | 
| 
       53 
     | 
    
         
            -
                # 
     | 
| 
       54 
     | 
    
         
            -
                # 
     | 
| 
       55 
     | 
    
         
            -
                # 
     | 
| 
       56 
     | 
    
         
            -
                # 
     | 
| 
       57 
     | 
    
         
            -
                # 
     | 
| 
       58 
     | 
    
         
            -
                # 
     | 
| 
      
 53 
     | 
    
         
            +
                #   mail = MailFactory.new
         
     | 
| 
      
 54 
     | 
    
         
            +
                #   mail.to = 'someone@site.co'
         
     | 
| 
      
 55 
     | 
    
         
            +
                #   mail.from = 'me@site.com'
         
     | 
| 
      
 56 
     | 
    
         
            +
                #   mail.subject = 'hi!'
         
     | 
| 
      
 57 
     | 
    
         
            +
                #   mail.text = 'hello world'
         
     | 
| 
      
 58 
     | 
    
         
            +
                #   mail.html = '<h1>hello world</h1>'
         
     | 
| 
       59 
59 
     | 
    
         
             
                #
         
     | 
| 
       60 
     | 
    
         
            -
                # 
     | 
| 
       61 
     | 
    
         
            -
                # 
     | 
| 
       62 
     | 
    
         
            -
                # 
     | 
| 
       63 
     | 
    
         
            -
                # 
     | 
| 
       64 
     | 
    
         
            -
                # 
     | 
| 
       65 
     | 
    
         
            -
                # 
     | 
| 
      
 60 
     | 
    
         
            +
                #   email = EM::P::SmtpClient.send(
         
     | 
| 
      
 61 
     | 
    
         
            +
                #     :domain=>'site.com',
         
     | 
| 
      
 62 
     | 
    
         
            +
                #     :from=>mail.from,
         
     | 
| 
      
 63 
     | 
    
         
            +
                #     :to=>mail.to,
         
     | 
| 
      
 64 
     | 
    
         
            +
                #     :content=>"#{mail.to_s}\r\n.\r\n"
         
     | 
| 
      
 65 
     | 
    
         
            +
                #   )
         
     | 
| 
       66 
66 
     | 
    
         
             
                #
         
     | 
| 
       67 
67 
     | 
    
         
             
                class SmtpClient < Connection
         
     | 
| 
       68 
68 
     | 
    
         
             
                  include EventMachine::Deferrable
         
     | 
    
        data/lib/em/threaded_resource.rb
    CHANGED
    
    | 
         @@ -29,7 +29,7 @@ module EventMachine 
     | 
|
| 
       29 
29 
     | 
    
         
             
              #
         
     | 
| 
       30 
30 
     | 
    
         
             
              #    # If we don't care about the result:
         
     | 
| 
       31 
31 
     | 
    
         
             
              #    pool.perform do |dispatcher|
         
     | 
| 
       32 
     | 
    
         
            -
              #      # The following  
     | 
| 
      
 32 
     | 
    
         
            +
              #      # The following block executes inside a dedicated thread, and should not
         
     | 
| 
       33 
33 
     | 
    
         
             
              #      # access EventMachine things:
         
     | 
| 
       34 
34 
     | 
    
         
             
              #      dispatcher.dispatch do |cassandra|
         
     | 
| 
       35 
35 
     | 
    
         
             
              #        cassandra.insert(:Things, '10', 'stuff' => 'things')
         
     | 
    
        data/lib/em/version.rb
    CHANGED
    
    
    
        data/lib/eventmachine.rb
    CHANGED
    
    | 
         @@ -82,7 +82,8 @@ module EventMachine 
     | 
|
| 
       82 
82 
     | 
    
         
             
              @reactor_running = false
         
     | 
| 
       83 
83 
     | 
    
         
             
              @next_tick_queue = []
         
     | 
| 
       84 
84 
     | 
    
         
             
              @tails = []
         
     | 
| 
       85 
     | 
    
         
            -
              @threadpool = nil
         
     | 
| 
      
 85 
     | 
    
         
            +
              @threadpool = @threadqueue = @resultqueue = nil
         
     | 
| 
      
 86 
     | 
    
         
            +
              @all_threads_spawned = false
         
     | 
| 
       86 
87 
     | 
    
         | 
| 
       87 
88 
     | 
    
         
             
              # System errnos
         
     | 
| 
       88 
89 
     | 
    
         
             
              # @private
         
     | 
| 
         @@ -155,7 +156,13 @@ module EventMachine 
     | 
|
| 
       155 
156 
     | 
    
         
             
                # will start without release_machine being called and will immediately throw
         
     | 
| 
       156 
157 
     | 
    
         | 
| 
       157 
158 
     | 
    
         
             
                #
         
     | 
| 
       158 
     | 
    
         
            -
             
     | 
| 
      
 159 
     | 
    
         
            +
                if reactor_running? and @reactor_pid != Process.pid
         
     | 
| 
      
 160 
     | 
    
         
            +
                  # Reactor was started in a different parent, meaning we have forked.
         
     | 
| 
      
 161 
     | 
    
         
            +
                  # Clean up reactor state so a new reactor boots up in this child.
         
     | 
| 
      
 162 
     | 
    
         
            +
                  stop_event_loop
         
     | 
| 
      
 163 
     | 
    
         
            +
                  release_machine
         
     | 
| 
      
 164 
     | 
    
         
            +
                  @reactor_running = false
         
     | 
| 
      
 165 
     | 
    
         
            +
                end
         
     | 
| 
       159 
166 
     | 
    
         | 
| 
       160 
167 
     | 
    
         
             
                tail and @tails.unshift(tail)
         
     | 
| 
       161 
168 
     | 
    
         | 
| 
         @@ -169,6 +176,7 @@ module EventMachine 
     | 
|
| 
       169 
176 
     | 
    
         
             
                  @next_tick_queue ||= []
         
     | 
| 
       170 
177 
     | 
    
         
             
                  @tails ||= []
         
     | 
| 
       171 
178 
     | 
    
         
             
                  begin
         
     | 
| 
      
 179 
     | 
    
         
            +
                    @reactor_pid = Process.pid
         
     | 
| 
       172 
180 
     | 
    
         
             
                    @reactor_running = true
         
     | 
| 
       173 
181 
     | 
    
         
             
                    initialize_event_machine
         
     | 
| 
       174 
182 
     | 
    
         
             
                    (b = blk || block) and add_timer(0, b)
         
     | 
| 
         @@ -201,6 +209,7 @@ module EventMachine 
     | 
|
| 
       201 
209 
     | 
    
         
             
                        @threadqueue = nil
         
     | 
| 
       202 
210 
     | 
    
         
             
                        @resultqueue = nil
         
     | 
| 
       203 
211 
     | 
    
         
             
                        @threadpool = nil
         
     | 
| 
      
 212 
     | 
    
         
            +
                        @all_threads_spawned = false
         
     | 
| 
       204 
213 
     | 
    
         
             
                      end
         
     | 
| 
       205 
214 
     | 
    
         | 
| 
       206 
215 
     | 
    
         
             
                      @next_tick_queue = []
         
     | 
| 
         @@ -252,7 +261,7 @@ module EventMachine 
     | 
|
| 
       252 
261 
     | 
    
         
             
                  if self.reactor_running?
         
     | 
| 
       253 
262 
     | 
    
         
             
                    self.stop_event_loop
         
     | 
| 
       254 
263 
     | 
    
         
             
                    self.release_machine
         
     | 
| 
       255 
     | 
    
         
            -
                     
     | 
| 
      
 264 
     | 
    
         
            +
                    @reactor_running = false
         
     | 
| 
       256 
265 
     | 
    
         
             
                  end
         
     | 
| 
       257 
266 
     | 
    
         
             
                  self.run block
         
     | 
| 
       258 
267 
     | 
    
         
             
                end
         
     | 
| 
         @@ -425,7 +434,8 @@ module EventMachine 
     | 
|
| 
       425 
434 
     | 
    
         
             
              # that you must define. When the network server that is started by
         
     | 
| 
       426 
435 
     | 
    
         
             
              # start_server accepts a new connection, it instantiates a new
         
     | 
| 
       427 
436 
     | 
    
         
             
              # object of an anonymous class that is inherited from {EventMachine::Connection},
         
     | 
| 
       428 
     | 
    
         
            -
              # *into which your handler module have been included*.
         
     | 
| 
      
 437 
     | 
    
         
            +
              # *into which your handler module have been included*. Arguments passed into start_server
         
     | 
| 
      
 438 
     | 
    
         
            +
              # after the class name are passed into the constructor during the instantiation.
         
     | 
| 
       429 
439 
     | 
    
         
             
              #
         
     | 
| 
       430 
440 
     | 
    
         
             
              # Your handler module may override any of the methods in {EventMachine::Connection},
         
     | 
| 
       431 
441 
     | 
    
         
             
              # such as {EventMachine::Connection#receive_data}, in order to implement the specific behavior
         
     | 
| 
         @@ -736,6 +746,7 @@ module EventMachine 
     | 
|
| 
       736 
746 
     | 
    
         
             
                c = klass.new s, *args
         
     | 
| 
       737 
747 
     | 
    
         | 
| 
       738 
748 
     | 
    
         
             
                c.instance_variable_set(:@io, io)
         
     | 
| 
      
 749 
     | 
    
         
            +
                c.instance_variable_set(:@watch_mode, watch_mode)
         
     | 
| 
       739 
750 
     | 
    
         
             
                c.instance_variable_set(:@fd, fd)
         
     | 
| 
       740 
751 
     | 
    
         | 
| 
       741 
752 
     | 
    
         
             
                @conns[s] = c
         
     | 
| 
         @@ -761,7 +772,11 @@ module EventMachine 
     | 
|
| 
       761 
772 
     | 
    
         
             
                #raise "still connected" if @conns.has_key?(handler.signature)
         
     | 
| 
       762 
773 
     | 
    
         
             
                return handler if @conns.has_key?(handler.signature)
         
     | 
| 
       763 
774 
     | 
    
         | 
| 
       764 
     | 
    
         
            -
                s =  
     | 
| 
      
 775 
     | 
    
         
            +
                s = if port
         
     | 
| 
      
 776 
     | 
    
         
            +
                      connect_server server, port
         
     | 
| 
      
 777 
     | 
    
         
            +
                    else
         
     | 
| 
      
 778 
     | 
    
         
            +
                      connect_unix_server server
         
     | 
| 
      
 779 
     | 
    
         
            +
                    end
         
     | 
| 
       765 
780 
     | 
    
         
             
                handler.signature = s
         
     | 
| 
       766 
781 
     | 
    
         
             
                @conns[s] = handler
         
     | 
| 
       767 
782 
     | 
    
         
             
                block_given? and yield handler
         
     | 
| 
         @@ -936,10 +951,21 @@ module EventMachine 
     | 
|
| 
       936 
951 
     | 
    
         
             
                  cback.call result if cback
         
     | 
| 
       937 
952 
     | 
    
         
             
                end
         
     | 
| 
       938 
953 
     | 
    
         | 
| 
       939 
     | 
    
         
            -
                 
     | 
| 
       940 
     | 
    
         
            -
             
     | 
| 
       941 
     | 
    
         
            -
             
     | 
| 
       942 
     | 
    
         
            -
             
     | 
| 
      
 954 
     | 
    
         
            +
                # Capture the size at the start of this tick...
         
     | 
| 
      
 955 
     | 
    
         
            +
                size = @next_tick_mutex.synchronize { @next_tick_queue.size }
         
     | 
| 
      
 956 
     | 
    
         
            +
                size.times do |i|
         
     | 
| 
      
 957 
     | 
    
         
            +
                  callback = @next_tick_mutex.synchronize { @next_tick_queue.shift }
         
     | 
| 
      
 958 
     | 
    
         
            +
                  begin
         
     | 
| 
      
 959 
     | 
    
         
            +
                    callback.call
         
     | 
| 
      
 960 
     | 
    
         
            +
                  ensure
         
     | 
| 
      
 961 
     | 
    
         
            +
                    # This is a little nasty. The problem is, if an exception occurs during
         
     | 
| 
      
 962 
     | 
    
         
            +
                    # the callback, then we need to send a signal to the reactor to actually
         
     | 
| 
      
 963 
     | 
    
         
            +
                    # do some work during the next_tick. The only mechanism we have from the
         
     | 
| 
      
 964 
     | 
    
         
            +
                    # ruby side is next_tick itself, although ideally, we'd just drop a byte
         
     | 
| 
      
 965 
     | 
    
         
            +
                    # on the loopback descriptor.
         
     | 
| 
      
 966 
     | 
    
         
            +
                    EM.next_tick {} if $!
         
     | 
| 
      
 967 
     | 
    
         
            +
                  end
         
     | 
| 
      
 968 
     | 
    
         
            +
                end
         
     | 
| 
       943 
969 
     | 
    
         
             
              end
         
     | 
| 
       944 
970 
     | 
    
         | 
| 
       945 
971 
     | 
    
         | 
| 
         @@ -991,7 +1017,6 @@ module EventMachine 
     | 
|
| 
       991 
1017 
     | 
    
         
             
                # has no constructor.
         
     | 
| 
       992 
1018 
     | 
    
         | 
| 
       993 
1019 
     | 
    
         
             
                unless @threadpool
         
     | 
| 
       994 
     | 
    
         
            -
                  require 'thread'
         
     | 
| 
       995 
1020 
     | 
    
         
             
                  @threadpool = []
         
     | 
| 
       996 
1021 
     | 
    
         
             
                  @threadqueue = ::Queue.new
         
     | 
| 
       997 
1022 
     | 
    
         
             
                  @resultqueue = ::Queue.new
         
     | 
| 
         @@ -1016,6 +1041,19 @@ module EventMachine 
     | 
|
| 
       1016 
1041 
     | 
    
         
             
                  end
         
     | 
| 
       1017 
1042 
     | 
    
         
             
                  @threadpool << thread
         
     | 
| 
       1018 
1043 
     | 
    
         
             
                end
         
     | 
| 
      
 1044 
     | 
    
         
            +
                @all_threads_spawned = true
         
     | 
| 
      
 1045 
     | 
    
         
            +
              end
         
     | 
| 
      
 1046 
     | 
    
         
            +
             
     | 
| 
      
 1047 
     | 
    
         
            +
              ##
         
     | 
| 
      
 1048 
     | 
    
         
            +
              # Returns +true+ if all deferred actions are done executing and their
         
     | 
| 
      
 1049 
     | 
    
         
            +
              # callbacks have been fired.
         
     | 
| 
      
 1050 
     | 
    
         
            +
              #
         
     | 
| 
      
 1051 
     | 
    
         
            +
              def self.defers_finished?
         
     | 
| 
      
 1052 
     | 
    
         
            +
                return false if @threadpool and !@all_threads_spawned
         
     | 
| 
      
 1053 
     | 
    
         
            +
                return false if @threadqueue and not @threadqueue.empty?
         
     | 
| 
      
 1054 
     | 
    
         
            +
                return false if @resultqueue and not @resultqueue.empty?
         
     | 
| 
      
 1055 
     | 
    
         
            +
                return false if @threadpool and @threadqueue.num_waiting != @threadpool.size
         
     | 
| 
      
 1056 
     | 
    
         
            +
                return true
         
     | 
| 
       1019 
1057 
     | 
    
         
             
              end
         
     | 
| 
       1020 
1058 
     | 
    
         | 
| 
       1021 
1059 
     | 
    
         
             
              class << self
         
     | 
| 
         @@ -1391,11 +1429,19 @@ module EventMachine 
     | 
|
| 
       1391 
1429 
     | 
    
         
             
                if opcode == ConnectionUnbound
         
     | 
| 
       1392 
1430 
     | 
    
         
             
                  if c = @conns.delete( conn_binding )
         
     | 
| 
       1393 
1431 
     | 
    
         
             
                    begin
         
     | 
| 
       1394 
     | 
    
         
            -
                      if c.original_method(:unbind).arity  
     | 
| 
      
 1432 
     | 
    
         
            +
                      if c.original_method(:unbind).arity != 0
         
     | 
| 
       1395 
1433 
     | 
    
         
             
                        c.unbind(data == 0 ? nil : EventMachine::ERRNOS[data])
         
     | 
| 
       1396 
1434 
     | 
    
         
             
                      else
         
     | 
| 
       1397 
1435 
     | 
    
         
             
                        c.unbind
         
     | 
| 
       1398 
1436 
     | 
    
         
             
                      end
         
     | 
| 
      
 1437 
     | 
    
         
            +
                      # If this is an attached (but not watched) connection, close the underlying io object.
         
     | 
| 
      
 1438 
     | 
    
         
            +
                      if c.instance_variable_defined?(:@io) and !c.instance_variable_get(:@watch_mode)
         
     | 
| 
      
 1439 
     | 
    
         
            +
                        io = c.instance_variable_get(:@io)
         
     | 
| 
      
 1440 
     | 
    
         
            +
                        begin
         
     | 
| 
      
 1441 
     | 
    
         
            +
                          io.close
         
     | 
| 
      
 1442 
     | 
    
         
            +
                        rescue Errno::EBADF, IOError
         
     | 
| 
      
 1443 
     | 
    
         
            +
                        end
         
     | 
| 
      
 1444 
     | 
    
         
            +
                      end
         
     | 
| 
       1399 
1445 
     | 
    
         
             
                    rescue
         
     | 
| 
       1400 
1446 
     | 
    
         
             
                      @wrapped_exception = $!
         
     | 
| 
       1401 
1447 
     | 
    
         
             
                      stop
         
     | 
    
        data/lib/jeventmachine.rb
    CHANGED
    
    | 
         @@ -203,6 +203,11 @@ module EventMachine 
     | 
|
| 
       203 
203 
     | 
    
         
             
                  Socket.pack_sockaddr_in(*peer)
         
     | 
| 
       204 
204 
     | 
    
         
             
                end
         
     | 
| 
       205 
205 
     | 
    
         
             
              end
         
     | 
| 
      
 206 
     | 
    
         
            +
              def self.get_sockname sig
         
     | 
| 
      
 207 
     | 
    
         
            +
                if sockName = @em.getSockName(sig)
         
     | 
| 
      
 208 
     | 
    
         
            +
                  Socket.pack_sockaddr_in(*sockName)
         
     | 
| 
      
 209 
     | 
    
         
            +
                end
         
     | 
| 
      
 210 
     | 
    
         
            +
              end
         
     | 
| 
       206 
211 
     | 
    
         
             
              # @private
         
     | 
| 
       207 
212 
     | 
    
         
             
              def self.attach_fd fileno, watch_mode
         
     | 
| 
       208 
213 
     | 
    
         
             
                # 3Aug09: We could pass in the actual SocketChannel, but then it would be modified (set as non-blocking), and
         
     | 
| 
         
            File without changes
         
     | 
| 
         
            File without changes
         
     | 
    
        data/{tasks → rakelib}/test.rake
    RENAMED
    
    | 
         
            File without changes
         
     | 
    
        data/tests/test_basic.rb
    CHANGED
    
    | 
         @@ -224,4 +224,71 @@ class TestBasic < Test::Unit::TestCase 
     | 
|
| 
       224 
224 
     | 
    
         
             
                  end
         
     | 
| 
       225 
225 
     | 
    
         
             
                end
         
     | 
| 
       226 
226 
     | 
    
         
             
              end
         
     | 
| 
      
 227 
     | 
    
         
            +
              
         
     | 
| 
      
 228 
     | 
    
         
            +
              def test_schedule_close
         
     | 
| 
      
 229 
     | 
    
         
            +
                localhost, port = '127.0.0.1', 9000
         
     | 
| 
      
 230 
     | 
    
         
            +
                timer_ran = false
         
     | 
| 
      
 231 
     | 
    
         
            +
                num_close_scheduled = nil
         
     | 
| 
      
 232 
     | 
    
         
            +
                EM.run do
         
     | 
| 
      
 233 
     | 
    
         
            +
                  assert_equal 0, EM.num_close_scheduled
         
     | 
| 
      
 234 
     | 
    
         
            +
                  EM.add_timer(1) { timer_ran = true; EM.stop }
         
     | 
| 
      
 235 
     | 
    
         
            +
                  EM.start_server localhost, port do |s|
         
     | 
| 
      
 236 
     | 
    
         
            +
                    s.close_connection
         
     | 
| 
      
 237 
     | 
    
         
            +
                    num_close_scheduled = EM.num_close_scheduled
         
     | 
| 
      
 238 
     | 
    
         
            +
                  end
         
     | 
| 
      
 239 
     | 
    
         
            +
                  EM.connect localhost, port do |c|
         
     | 
| 
      
 240 
     | 
    
         
            +
                    def c.unbind
         
     | 
| 
      
 241 
     | 
    
         
            +
                      EM.stop
         
     | 
| 
      
 242 
     | 
    
         
            +
                    end
         
     | 
| 
      
 243 
     | 
    
         
            +
                  end
         
     | 
| 
      
 244 
     | 
    
         
            +
                end
         
     | 
| 
      
 245 
     | 
    
         
            +
                assert !timer_ran
         
     | 
| 
      
 246 
     | 
    
         
            +
                assert_equal 1, num_close_scheduled
         
     | 
| 
      
 247 
     | 
    
         
            +
              end
         
     | 
| 
      
 248 
     | 
    
         
            +
             
     | 
| 
      
 249 
     | 
    
         
            +
              def test_fork_safe
         
     | 
| 
      
 250 
     | 
    
         
            +
                return unless cpid = fork { exit! } rescue false
         
     | 
| 
      
 251 
     | 
    
         
            +
             
     | 
| 
      
 252 
     | 
    
         
            +
                read, write = IO.pipe
         
     | 
| 
      
 253 
     | 
    
         
            +
                EM.run do
         
     | 
| 
      
 254 
     | 
    
         
            +
                  cpid = fork do
         
     | 
| 
      
 255 
     | 
    
         
            +
                    write.puts "forked"
         
     | 
| 
      
 256 
     | 
    
         
            +
                    EM.run do
         
     | 
| 
      
 257 
     | 
    
         
            +
                      EM.next_tick do
         
     | 
| 
      
 258 
     | 
    
         
            +
                        write.puts "EM ran"
         
     | 
| 
      
 259 
     | 
    
         
            +
                        exit!
         
     | 
| 
      
 260 
     | 
    
         
            +
                      end
         
     | 
| 
      
 261 
     | 
    
         
            +
                    end
         
     | 
| 
      
 262 
     | 
    
         
            +
                  end
         
     | 
| 
      
 263 
     | 
    
         
            +
                  EM.stop
         
     | 
| 
      
 264 
     | 
    
         
            +
                end
         
     | 
| 
      
 265 
     | 
    
         
            +
                Process.waitall
         
     | 
| 
      
 266 
     | 
    
         
            +
                assert_equal "forked\n", read.readline
         
     | 
| 
      
 267 
     | 
    
         
            +
                assert_equal "EM ran\n", read.readline
         
     | 
| 
      
 268 
     | 
    
         
            +
              ensure
         
     | 
| 
      
 269 
     | 
    
         
            +
                read.close rescue nil
         
     | 
| 
      
 270 
     | 
    
         
            +
                write.close rescue nil
         
     | 
| 
      
 271 
     | 
    
         
            +
              end
         
     | 
| 
      
 272 
     | 
    
         
            +
             
     | 
| 
      
 273 
     | 
    
         
            +
              def test_error_handler_idempotent # issue 185
         
     | 
| 
      
 274 
     | 
    
         
            +
                errors = []
         
     | 
| 
      
 275 
     | 
    
         
            +
                ticks = []
         
     | 
| 
      
 276 
     | 
    
         
            +
                EM.error_handler do |e|
         
     | 
| 
      
 277 
     | 
    
         
            +
                  errors << e
         
     | 
| 
      
 278 
     | 
    
         
            +
                end
         
     | 
| 
      
 279 
     | 
    
         
            +
             
     | 
| 
      
 280 
     | 
    
         
            +
                EM.run do
         
     | 
| 
      
 281 
     | 
    
         
            +
                  EM.next_tick do
         
     | 
| 
      
 282 
     | 
    
         
            +
                    ticks << :first
         
     | 
| 
      
 283 
     | 
    
         
            +
                    raise
         
     | 
| 
      
 284 
     | 
    
         
            +
                  end
         
     | 
| 
      
 285 
     | 
    
         
            +
                  EM.next_tick do
         
     | 
| 
      
 286 
     | 
    
         
            +
                    ticks << :second
         
     | 
| 
      
 287 
     | 
    
         
            +
                  end
         
     | 
| 
      
 288 
     | 
    
         
            +
                  EM.add_timer(0.001) { EM.stop }
         
     | 
| 
      
 289 
     | 
    
         
            +
                end
         
     | 
| 
      
 290 
     | 
    
         
            +
             
     | 
| 
      
 291 
     | 
    
         
            +
                assert_equal 1, errors.size
         
     | 
| 
      
 292 
     | 
    
         
            +
                assert_equal [:first, :second], ticks
         
     | 
| 
      
 293 
     | 
    
         
            +
              end
         
     | 
| 
       227 
294 
     | 
    
         
             
            end
         
     | 
| 
         @@ -0,0 +1,23 @@ 
     | 
|
| 
      
 1 
     | 
    
         
            +
            require 'em_test_helper'
         
     | 
| 
      
 2 
     | 
    
         
            +
             
     | 
| 
      
 3 
     | 
    
         
            +
            class TestIdleConnection < Test::Unit::TestCase
         
     | 
| 
      
 4 
     | 
    
         
            +
              if EM.respond_to?(:get_idle_time)
         
     | 
| 
      
 5 
     | 
    
         
            +
                def test_idle_time
         
     | 
| 
      
 6 
     | 
    
         
            +
                  EM.run{
         
     | 
| 
      
 7 
     | 
    
         
            +
                    conn = EM.connect 'www.google.com', 80
         
     | 
| 
      
 8 
     | 
    
         
            +
                    EM.add_timer(3){
         
     | 
| 
      
 9 
     | 
    
         
            +
                      $idle_time = conn.get_idle_time
         
     | 
| 
      
 10 
     | 
    
         
            +
                      conn.send_data "GET / HTTP/1.0\r\n\r\n"
         
     | 
| 
      
 11 
     | 
    
         
            +
                      EM.next_tick{
         
     | 
| 
      
 12 
     | 
    
         
            +
                        $idle_time_after_send = conn.get_idle_time
         
     | 
| 
      
 13 
     | 
    
         
            +
                        conn.close_connection
         
     | 
| 
      
 14 
     | 
    
         
            +
                        EM.stop
         
     | 
| 
      
 15 
     | 
    
         
            +
                      }
         
     | 
| 
      
 16 
     | 
    
         
            +
                    }
         
     | 
| 
      
 17 
     | 
    
         
            +
                  }
         
     | 
| 
      
 18 
     | 
    
         
            +
             
     | 
| 
      
 19 
     | 
    
         
            +
                  assert_in_delta 3, $idle_time, 0.2
         
     | 
| 
      
 20 
     | 
    
         
            +
                  assert_equal 0, $idle_time_after_send
         
     | 
| 
      
 21 
     | 
    
         
            +
                end
         
     | 
| 
      
 22 
     | 
    
         
            +
              end
         
     | 
| 
      
 23 
     | 
    
         
            +
            end
         
     | 
    
        data/tests/test_pool.rb
    CHANGED
    
    | 
         @@ -115,6 +115,41 @@ class TestPool < Test::Unit::TestCase 
     | 
|
| 
       115 
115 
     | 
    
         
             
                assert_equal [:res], pool.contents
         
     | 
| 
       116 
116 
     | 
    
         
             
              end
         
     | 
| 
       117 
117 
     | 
    
         | 
| 
      
 118 
     | 
    
         
            +
              def test_contents_when_perform_errors_and_on_error_is_not_set
         
     | 
| 
      
 119 
     | 
    
         
            +
                pool.add :res
         
     | 
| 
      
 120 
     | 
    
         
            +
                assert_equal [:res], pool.contents
         
     | 
| 
      
 121 
     | 
    
         
            +
             
     | 
| 
      
 122 
     | 
    
         
            +
                pool.perform do |r|
         
     | 
| 
      
 123 
     | 
    
         
            +
                  d = EM::DefaultDeferrable.new
         
     | 
| 
      
 124 
     | 
    
         
            +
                  d.fail
         
     | 
| 
      
 125 
     | 
    
         
            +
                  d
         
     | 
| 
      
 126 
     | 
    
         
            +
                end
         
     | 
| 
      
 127 
     | 
    
         
            +
             
     | 
| 
      
 128 
     | 
    
         
            +
                EM.run { EM.next_tick { EM.stop } }
         
     | 
| 
      
 129 
     | 
    
         
            +
             
     | 
| 
      
 130 
     | 
    
         
            +
                assert_equal [:res], pool.contents
         
     | 
| 
      
 131 
     | 
    
         
            +
              end
         
     | 
| 
      
 132 
     | 
    
         
            +
             
     | 
| 
      
 133 
     | 
    
         
            +
              def test_contents_when_perform_errors_and_on_error_is_set
         
     | 
| 
      
 134 
     | 
    
         
            +
                pool.add :res
         
     | 
| 
      
 135 
     | 
    
         
            +
                res = nil
         
     | 
| 
      
 136 
     | 
    
         
            +
                pool.on_error do |r|
         
     | 
| 
      
 137 
     | 
    
         
            +
                  res = r
         
     | 
| 
      
 138 
     | 
    
         
            +
                end
         
     | 
| 
      
 139 
     | 
    
         
            +
                assert_equal [:res], pool.contents
         
     | 
| 
      
 140 
     | 
    
         
            +
             
     | 
| 
      
 141 
     | 
    
         
            +
                pool.perform do |r|
         
     | 
| 
      
 142 
     | 
    
         
            +
                  d = EM::DefaultDeferrable.new
         
     | 
| 
      
 143 
     | 
    
         
            +
                  d.fail 'foo'
         
     | 
| 
      
 144 
     | 
    
         
            +
                  d
         
     | 
| 
      
 145 
     | 
    
         
            +
                end
         
     | 
| 
      
 146 
     | 
    
         
            +
             
     | 
| 
      
 147 
     | 
    
         
            +
                EM.run { EM.next_tick { EM.stop } }
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
      
 149 
     | 
    
         
            +
                assert_equal :res, res
         
     | 
| 
      
 150 
     | 
    
         
            +
                assert_equal [], pool.contents
         
     | 
| 
      
 151 
     | 
    
         
            +
              end
         
     | 
| 
      
 152 
     | 
    
         
            +
             
     | 
| 
       118 
153 
     | 
    
         
             
              def test_num_waiting
         
     | 
| 
       119 
154 
     | 
    
         
             
                pool.add :res
         
     | 
| 
       120 
155 
     | 
    
         
             
                assert_equal 0, pool.num_waiting
         
     | 
| 
         @@ -125,4 +160,35 @@ class TestPool < Test::Unit::TestCase 
     | 
|
| 
       125 
160 
     | 
    
         
             
                assert_equal 10, pool.num_waiting
         
     | 
| 
       126 
161 
     | 
    
         
             
              end
         
     | 
| 
       127 
162 
     | 
    
         | 
| 
       128 
     | 
    
         
            -
             
     | 
| 
      
 163 
     | 
    
         
            +
              def test_exceptions_in_the_work_block_bubble_up_raise_and_fail_the_resource
         
     | 
| 
      
 164 
     | 
    
         
            +
                pool.add :res
         
     | 
| 
      
 165 
     | 
    
         
            +
             
     | 
| 
      
 166 
     | 
    
         
            +
                res = nil
         
     | 
| 
      
 167 
     | 
    
         
            +
                pool.on_error { |r| res = r }
         
     | 
| 
      
 168 
     | 
    
         
            +
                pool.perform { raise 'boom' }
         
     | 
| 
      
 169 
     | 
    
         
            +
             
     | 
| 
      
 170 
     | 
    
         
            +
                assert_raises(RuntimeError) do
         
     | 
| 
      
 171 
     | 
    
         
            +
                  EM.run { EM.next_tick { EM.stop } }
         
     | 
| 
      
 172 
     | 
    
         
            +
                end
         
     | 
| 
      
 173 
     | 
    
         
            +
             
     | 
| 
      
 174 
     | 
    
         
            +
                assert_equal [], pool.contents
         
     | 
| 
      
 175 
     | 
    
         
            +
                assert_equal :res, res
         
     | 
| 
      
 176 
     | 
    
         
            +
              end
         
     | 
| 
      
 177 
     | 
    
         
            +
             
     | 
| 
      
 178 
     | 
    
         
            +
              def test_removed_list_does_not_leak_on_errors
         
     | 
| 
      
 179 
     | 
    
         
            +
                pool.add :res
         
     | 
| 
      
 180 
     | 
    
         
            +
             
     | 
| 
      
 181 
     | 
    
         
            +
                pool.on_error do |r|
         
     | 
| 
      
 182 
     | 
    
         
            +
                  # This is actually the wrong thing to do, and not required, but some users
         
     | 
| 
      
 183 
     | 
    
         
            +
                  # might do it. When they do, they would find that @removed would cause a
         
     | 
| 
      
 184 
     | 
    
         
            +
                  # slow leak.
         
     | 
| 
      
 185 
     | 
    
         
            +
                  pool.remove r
         
     | 
| 
      
 186 
     | 
    
         
            +
                end
         
     | 
| 
      
 187 
     | 
    
         
            +
             
     | 
| 
      
 188 
     | 
    
         
            +
                pool.perform { d = EM::DefaultDeferrable.new; d.fail; d }
         
     | 
| 
      
 189 
     | 
    
         
            +
             
     | 
| 
      
 190 
     | 
    
         
            +
                EM.run { EM.next_tick { EM.stop } }
         
     | 
| 
      
 191 
     | 
    
         
            +
                assert_equal [], pool.instance_variable_get(:@removed)
         
     | 
| 
      
 192 
     | 
    
         
            +
              end
         
     | 
| 
      
 193 
     | 
    
         
            +
             
     | 
| 
      
 194 
     | 
    
         
            +
            end
         
     | 
| 
         @@ -24,6 +24,7 @@ class TestProxyConnection < Test::Unit::TestCase 
     | 
|
| 
       24 
24 
     | 
    
         
             
                  end
         
     | 
| 
       25 
25 
     | 
    
         | 
| 
       26 
26 
     | 
    
         
             
                  def unbind
         
     | 
| 
      
 27 
     | 
    
         
            +
                    $proxied_bytes = self.get_proxied_bytes
         
     | 
| 
       27 
28 
     | 
    
         
             
                    @client.close_connection_after_writing
         
     | 
| 
       28 
29 
     | 
    
         
             
                  end
         
     | 
| 
       29 
30 
     | 
    
         
             
                end
         
     | 
| 
         @@ -94,7 +95,7 @@ class TestProxyConnection < Test::Unit::TestCase 
     | 
|
| 
       94 
95 
     | 
    
         
             
                  end
         
     | 
| 
       95 
96 
     | 
    
         | 
| 
       96 
97 
     | 
    
         
             
                  def receive_data(data)
         
     | 
| 
       97 
     | 
    
         
            -
                    EM.connect("127.0.0.1", @port, ProxyConnection, self, data)
         
     | 
| 
      
 98 
     | 
    
         
            +
                    @proxy = EM.connect("127.0.0.1", @port, ProxyConnection, self, data)
         
     | 
| 
       98 
99 
     | 
    
         
             
                  end
         
     | 
| 
       99 
100 
     | 
    
         
             
                end
         
     | 
| 
       100 
101 
     | 
    
         | 
| 
         @@ -134,6 +135,17 @@ class TestProxyConnection < Test::Unit::TestCase 
     | 
|
| 
       134 
135 
     | 
    
         
             
                  assert_equal("I know!", $client_data)
         
     | 
| 
       135 
136 
     | 
    
         
             
                end
         
     | 
| 
       136 
137 
     | 
    
         | 
| 
      
 138 
     | 
    
         
            +
                def test_proxied_bytes
         
     | 
| 
      
 139 
     | 
    
         
            +
                  EM.run {
         
     | 
| 
      
 140 
     | 
    
         
            +
                    EM.start_server("127.0.0.1", @port, Server)
         
     | 
| 
      
 141 
     | 
    
         
            +
                    EM.start_server("127.0.0.1", @proxy_port, ProxyServer, @port)
         
     | 
| 
      
 142 
     | 
    
         
            +
                    EM.connect("127.0.0.1", @proxy_port, Client)
         
     | 
| 
      
 143 
     | 
    
         
            +
                  }
         
     | 
| 
      
 144 
     | 
    
         
            +
             
     | 
| 
      
 145 
     | 
    
         
            +
                  assert_equal("I know!", $client_data)
         
     | 
| 
      
 146 
     | 
    
         
            +
                  assert_equal("I know!".bytesize, $proxied_bytes)
         
     | 
| 
      
 147 
     | 
    
         
            +
                end
         
     | 
| 
      
 148 
     | 
    
         
            +
             
     | 
| 
       137 
149 
     | 
    
         
             
                def test_partial_proxy_connection
         
     | 
| 
       138 
150 
     | 
    
         
             
                  EM.run {
         
     | 
| 
       139 
151 
     | 
    
         
             
                    EM.start_server("127.0.0.1", @port, Server)
         
     | 
    
        data/tests/test_unbind_reason.rb
    CHANGED
    
    | 
         @@ -2,6 +2,15 @@ require 'em_test_helper' 
     | 
|
| 
       2 
2 
     | 
    
         
             
            require 'socket'
         
     | 
| 
       3 
3 
     | 
    
         | 
| 
       4 
4 
     | 
    
         
             
            class TestUnbindReason < Test::Unit::TestCase
         
     | 
| 
      
 5 
     | 
    
         
            +
             
     | 
| 
      
 6 
     | 
    
         
            +
              class StubConnection < EM::Connection
         
     | 
| 
      
 7 
     | 
    
         
            +
                attr_reader :error
         
     | 
| 
      
 8 
     | 
    
         
            +
                def unbind(reason = nil)
         
     | 
| 
      
 9 
     | 
    
         
            +
                  @error = reason
         
     | 
| 
      
 10 
     | 
    
         
            +
                  EM.stop
         
     | 
| 
      
 11 
     | 
    
         
            +
                end
         
     | 
| 
      
 12 
     | 
    
         
            +
              end
         
     | 
| 
      
 13 
     | 
    
         
            +
             
     | 
| 
       5 
14 
     | 
    
         
             
              def test_connect_timeout
         
     | 
| 
       6 
15 
     | 
    
         
             
                error = nil
         
     | 
| 
       7 
16 
     | 
    
         
             
                EM.run {
         
     | 
| 
         @@ -13,7 +22,7 @@ class TestUnbindReason < Test::Unit::TestCase 
     | 
|
| 
       13 
22 
     | 
    
         
             
                  }
         
     | 
| 
       14 
23 
     | 
    
         
             
                  conn.pending_connect_timeout = 0.1
         
     | 
| 
       15 
24 
     | 
    
         
             
                }
         
     | 
| 
       16 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 25 
     | 
    
         
            +
                assert_equal Errno::ETIMEDOUT, error
         
     | 
| 
       17 
26 
     | 
    
         
             
              end
         
     | 
| 
       18 
27 
     | 
    
         | 
| 
       19 
28 
     | 
    
         
             
              def test_connect_refused
         
     | 
| 
         @@ -26,6 +35,14 @@ class TestUnbindReason < Test::Unit::TestCase 
     | 
|
| 
       26 
35 
     | 
    
         
             
                    end
         
     | 
| 
       27 
36 
     | 
    
         
             
                  }
         
     | 
| 
       28 
37 
     | 
    
         
             
                }
         
     | 
| 
       29 
     | 
    
         
            -
                assert_equal  
     | 
| 
      
 38 
     | 
    
         
            +
                assert_equal Errno::ECONNREFUSED, error
         
     | 
| 
      
 39 
     | 
    
         
            +
              end
         
     | 
| 
      
 40 
     | 
    
         
            +
             
     | 
| 
      
 41 
     | 
    
         
            +
              def test_optional_argument
         
     | 
| 
      
 42 
     | 
    
         
            +
                conn = nil
         
     | 
| 
      
 43 
     | 
    
         
            +
                EM.run {
         
     | 
| 
      
 44 
     | 
    
         
            +
                  conn = EM.connect '127.0.0.1', 12388, StubConnection
         
     | 
| 
      
 45 
     | 
    
         
            +
                }
         
     | 
| 
      
 46 
     | 
    
         
            +
                assert_equal Errno::ECONNREFUSED, conn.error
         
     | 
| 
       30 
47 
     | 
    
         
             
              end
         
     | 
| 
       31 
48 
     | 
    
         
             
            end
         
     | 
    
        metadata
    CHANGED
    
    | 
         @@ -1,15 +1,15 @@ 
     | 
|
| 
       1 
1 
     | 
    
         
             
            --- !ruby/object:Gem::Specification 
         
     | 
| 
       2 
2 
     | 
    
         
             
            name: eventmachine
         
     | 
| 
       3 
3 
     | 
    
         
             
            version: !ruby/object:Gem::Version 
         
     | 
| 
       4 
     | 
    
         
            -
              hash:  
     | 
| 
      
 4 
     | 
    
         
            +
              hash: 379161805
         
     | 
| 
       5 
5 
     | 
    
         
             
              prerelease: 6
         
     | 
| 
       6 
6 
     | 
    
         
             
              segments: 
         
     | 
| 
       7 
7 
     | 
    
         
             
              - 1
         
     | 
| 
       8 
8 
     | 
    
         
             
              - 0
         
     | 
| 
       9 
9 
     | 
    
         
             
              - 0
         
     | 
| 
       10 
     | 
    
         
            -
              -  
     | 
| 
       11 
     | 
    
         
            -
              -  
     | 
| 
       12 
     | 
    
         
            -
              version: 1.0.0. 
     | 
| 
      
 10 
     | 
    
         
            +
              - rc
         
     | 
| 
      
 11 
     | 
    
         
            +
              - 1
         
     | 
| 
      
 12 
     | 
    
         
            +
              version: 1.0.0.rc.1
         
     | 
| 
       13 
13 
     | 
    
         
             
            platform: x86-mingw32
         
     | 
| 
       14 
14 
     | 
    
         
             
            authors: 
         
     | 
| 
       15 
15 
     | 
    
         
             
            - Francis Cianfrocca
         
     | 
| 
         @@ -18,7 +18,7 @@ autorequire: 
     | 
|
| 
       18 
18 
     | 
    
         
             
            bindir: bin
         
     | 
| 
       19 
19 
     | 
    
         
             
            cert_chain: []
         
     | 
| 
       20 
20 
     | 
    
         | 
| 
       21 
     | 
    
         
            -
            date:  
     | 
| 
      
 21 
     | 
    
         
            +
            date: 2012-06-18 00:00:00 -07:00
         
     | 
| 
       22 
22 
     | 
    
         
             
            default_executable: 
         
     | 
| 
       23 
23 
     | 
    
         
             
            dependencies: 
         
     | 
| 
       24 
24 
     | 
    
         
             
            - !ruby/object:Gem::Dependency 
         
     | 
| 
         @@ -53,20 +53,6 @@ dependencies: 
     | 
|
| 
       53 
53 
     | 
    
         
             
                    version: 0.7.2
         
     | 
| 
       54 
54 
     | 
    
         
             
              type: :development
         
     | 
| 
       55 
55 
     | 
    
         
             
              version_requirements: *id002
         
     | 
| 
       56 
     | 
    
         
            -
            - !ruby/object:Gem::Dependency 
         
     | 
| 
       57 
     | 
    
         
            -
              name: bluecloth
         
     | 
| 
       58 
     | 
    
         
            -
              prerelease: false
         
     | 
| 
       59 
     | 
    
         
            -
              requirement: &id003 !ruby/object:Gem::Requirement 
         
     | 
| 
       60 
     | 
    
         
            -
                none: false
         
     | 
| 
       61 
     | 
    
         
            -
                requirements: 
         
     | 
| 
       62 
     | 
    
         
            -
                - - ">="
         
     | 
| 
       63 
     | 
    
         
            -
                  - !ruby/object:Gem::Version 
         
     | 
| 
       64 
     | 
    
         
            -
                    hash: 3
         
     | 
| 
       65 
     | 
    
         
            -
                    segments: 
         
     | 
| 
       66 
     | 
    
         
            -
                    - 0
         
     | 
| 
       67 
     | 
    
         
            -
                    version: "0"
         
     | 
| 
       68 
     | 
    
         
            -
              type: :development
         
     | 
| 
       69 
     | 
    
         
            -
              version_requirements: *id003
         
     | 
| 
       70 
56 
     | 
    
         
             
            description: |-
         
     | 
| 
       71 
57 
     | 
    
         
             
              EventMachine implements a fast, single-threaded engine for arbitrary network
         
     | 
| 
       72 
58 
     | 
    
         
             
              communications. It's extremely easy to use in Ruby. EventMachine wraps all
         
     | 
| 
         @@ -206,9 +192,9 @@ files: 
     | 
|
| 
       206 
192 
     | 
    
         
             
            - lib/em/version.rb
         
     | 
| 
       207 
193 
     | 
    
         
             
            - lib/eventmachine.rb
         
     | 
| 
       208 
194 
     | 
    
         
             
            - lib/jeventmachine.rb
         
     | 
| 
       209 
     | 
    
         
            -
            -  
     | 
| 
       210 
     | 
    
         
            -
            -  
     | 
| 
       211 
     | 
    
         
            -
            -  
     | 
| 
      
 195 
     | 
    
         
            +
            - rakelib/cpp.rake_example
         
     | 
| 
      
 196 
     | 
    
         
            +
            - rakelib/package.rake
         
     | 
| 
      
 197 
     | 
    
         
            +
            - rakelib/test.rake
         
     | 
| 
       212 
198 
     | 
    
         
             
            - tests/client.crt
         
     | 
| 
       213 
199 
     | 
    
         
             
            - tests/client.key
         
     | 
| 
       214 
200 
     | 
    
         
             
            - tests/em_test_helper.rb
         
     | 
| 
         @@ -229,6 +215,7 @@ files: 
     | 
|
| 
       229 
215 
     | 
    
         
             
            - tests/test_hc.rb
         
     | 
| 
       230 
216 
     | 
    
         
             
            - tests/test_httpclient.rb
         
     | 
| 
       231 
217 
     | 
    
         
             
            - tests/test_httpclient2.rb
         
     | 
| 
      
 218 
     | 
    
         
            +
            - tests/test_idle_connection.rb
         
     | 
| 
       232 
219 
     | 
    
         
             
            - tests/test_inactivity_timeout.rb
         
     | 
| 
       233 
220 
     | 
    
         
             
            - tests/test_kb.rb
         
     | 
| 
       234 
221 
     | 
    
         
             
            - tests/test_ltp.rb
         
     |