Ticket #33: assure_ends_well.diff
| File assure_ends_well.diff, 3.5 kB (added by rogerdpack, 5 months ago) |
|---|
-
ext/em.cpp
old new 463 463 // descriptor is closed anyway. This is different from the case where 464 464 // the socket has already been closed but the descriptor in the ED object 465 465 // hasn't yet been set to INVALID_SOCKET. 466 int i , j;466 int i; 467 467 int nSockets = Descriptors.size(); 468 for (i=0 , j=0; i < nSockets; i++) {468 for (i=0; i < nSockets; i++) { 469 469 EventableDescriptor *ed = Descriptors[i]; 470 470 assert (ed); 471 471 if (ed->ShouldDelete()) { … … 482 482 } 483 483 484 484 ModifiedDescriptors.erase (ed); 485 Descriptors[i] = Descriptors[Descriptors.size() - 1]; 486 Descriptors.pop_back(); 487 i--; nSockets--; 488 485 489 delete ed; 486 490 } 487 else488 Descriptors [j++] = ed;489 491 } 490 while ((size_t)j < Descriptors.size())491 Descriptors.pop_back();492 492 493 493 } 494 494 … … 556 556 // rather than traversing the whole list. 557 557 // In kqueue, closing a descriptor automatically removes its event filters. 558 558 559 int i , j;559 int i; 560 560 int nSockets = Descriptors.size(); 561 for (i=0 , j=0; i < nSockets; i++) {561 for (i=0; i < nSockets; i++) { 562 562 EventableDescriptor *ed = Descriptors[i]; 563 563 assert (ed); 564 564 if (ed->ShouldDelete()) { 565 565 ModifiedDescriptors.erase (ed); 566 566 delete ed; 567 Descriptors[i] = Descriptors[Descriptors.size() - 1]; // replace our 'gone' one with a live one 568 i--; nSockets--; 569 Descriptors.pop_back(); 567 570 } 568 else569 Descriptors [j++] = ed;570 571 } 571 while ((size_t)j < Descriptors.size())572 Descriptors.pop_back();573 572 574 573 } 575 574 … … 790 789 791 790 { // cleanup dying sockets 792 791 // vector::pop_back works in constant time. 793 int i , j;792 int i; 794 793 int nSockets = Descriptors.size(); 795 for (i=0 , j=0; i < nSockets; i++) {794 for (i=0; i < nSockets; i++) { 796 795 EventableDescriptor *ed = Descriptors[i]; 797 796 assert (ed); 798 797 if (ed->ShouldDelete()) 798 { 799 799 delete ed; 800 else 801 Descriptors [j++] = ed; 800 Descriptors[i] = Descriptors[Descriptors.size() - 1]; 801 Descriptors.pop_back(); 802 i--; nSockets--; 803 } 802 804 } 803 while ((size_t)j < Descriptors.size())804 Descriptors.pop_back();805 805 806 806 } 807 807 -
tests/test_ends_right.rb
old new 1 # this error occurs when you have several sockets, like 3 2 # they are all 'closed' but their descriptors are in the middle of being collected 3 # THEN the program terminates, which causes the EM thread to jump to its finalizer. 4 5 $:.unshift "../lib" 6 require 'eventmachine' 7 require 'test/unit' 8 9 module SlowClosers 10 @@total_closed = 0 11 12 def unbind 13 @@total_closed += 1 14 raise LocalJumpError.new() if @@total_closed == 2 15 end 16 17 end 18 19 class DeathEnd < Test::Unit::TestCase 20 21 def setup 22 SlowClosers.class_eval("@@total_closed = 0") 23 end 24 25 def test_ends_well_multi_thread # note that ideally it should try it with kqueue, epoll, and normal. I'm not sure if all the tests should just be re-run with those settings or what 26 begin 27 EM::run { 28 3.times {EM::connect '127.0.0.1', 6000, SlowClosers} 29 } 30 rescue LocalJumpError 31 # we should get here--if it errs it will err with a 'HARD' c-style error 32 end 33 end 34 35 # another test with possibility would be one that encourage the ConnectionUnbound caused if they 36 # do a connection or add_timer or start_server from another thread. Not sure if we want to care about that one [though we should, really]. 37 38 end 39
