Ok, let's see if we can get a grip on what is going on.

what I did was in
sqSocketCreateNetTypeSocketTypeRecvBytesSendBytesSemaIDReadSemaIDWriteSemaID

after the socket() call and at the check for socket value = -1, I  
always fail the primitive call.
This mimics what happens when you run out of socket handles.
In this case since we never recover then it should result in a hard  
failure because the socket table is full.

I put a break point in to understand where we are, and a breakpoint at  
the full GC.

What I see is the first call, where we fail.

current pharo, closure based, macintosh vm 4.1.1b2
Process
557974616 Socket>initialize:family:
557974524 >newTCP:
557974308 BlockClosure>repeatWithGCIf:
557974216 >newTCP:
557974124 >newTCP
557973968 >new
557652968 >sendTest
557652876 >?
557649476 Compiler>evaluate:in:to:notifying:ifFail:logged:
557649384 ParagraphEditor>evaluateSelection
557649228 BlockClosure>on:do:
557649136 ParagraphEditor>evaluateSelection
557649024 ParagraphEditor>doIt

The second call I note the full GC hasn't happened yet, so the code is  
invoking create new socket again before the GC call, which *IS* rather  
pointless.
I wonder why the second call happens before the GC?

Process
557976760  
Socket 
 > 
primSocketCreateNetwork:type:receiveBufferSize:sendBufSize:semaIndex:readSemaIndex:writeSemaIndex
 
:
557974616 Socket>initialize:family:
557974524 >newTCP:
557974308 BlockClosure>repeatWithGCIf:
557974216 >newTCP:
557974124 >newTCP
557973968 >new
557652968 >sendTest
557652876 >?
557649476 Compiler>evaluate:in:to:notifying:ifFail:logged:
557649384 ParagraphEditor>evaluateSelection
557649228 BlockClosure>on:do:
557649136 ParagraphEditor>evaluateSelection
557649024 ParagraphEditor>doIt

then we see the full GC which has the intent of cleaning out zombies  
so that those sockets can be returned to the operating system.


Process
557683240 SystemDictionary>garbageCollect
557683044 BlockClosure>repeatWithGCIf:
557682952 >newTCP:
557682860 >newTCP
557682768 >new
557652968 >sendTest
557652876 >?
557649476 Compiler>evaluate:in:to:notifying:ifFail:logged:
557649384 ParagraphEditor>evaluateSelection
557649228 BlockClosure>on:do:
557649136 ParagraphEditor>evaluateSelection
557649024 ParagraphEditor>doIt

then again

Process
556761248 Socket>initialize:family:
556719648 >newTCP:
556692112 BlockClosure>repeatWithGCIf:
556692020 >newTCP:
556691928 >newTCP
556691836 >new
556662076 >sendTest
556661984 >?
556658584 Compiler>evaluate:in:to:notifying:ifFail:logged:
556658492 ParagraphEditor>evaluateSelection
556658336 BlockClosure>on:do:
556658244 ParagraphEditor>evaluateSelection
556658132 ParagraphEditor>doIt

and again, which seems rather pointless.

Process
556763348  
Socket 
 > 
primSocketCreateNetwork:type:receiveBufferSize:sendBufSize:semaIndex:readSemaIndex:writeSemaIndex
 
:
556761248 Socket>initialize:family:
556719648 >newTCP:
556692112 BlockClosure>repeatWithGCIf:
556692020 >newTCP:
556691928 >newTCP
556691836 >new
556662076 >sendTest
556661984 >?
556658584 Compiler>evaluate:in:to:notifying:ifFail:logged:
5566584\92 ParagraphEditor>evaluateSelection
556658336 BlockClosure>on:do:
556658244 ParagraphEditor>evaluateSelection
556658132 ParagraphEditor>doIt


Then the walkback pops up.  Obviously should the code try to make the  
socket 4 times?   versus say twice?


Socket>>connectNonBlockingTo:
        Receiver: a Socket[destroyed]
        Arguments and temporary variables:
                aSocketAddress:         128.111.221.123(pulse),9(discard)
                status:         -1
        Receiver's instance variables:
                semaphore:      nil
                socketHandle:   nil
                readSemaphore:  nil
                writeSemaphore:         nil
                primitiveOnlySupportsOneSemaphore:      true

Socket>>connectTo:waitForConnectionFor:
        Receiver: a Socket[destroyed]
        Arguments and temporary variables:
                aSocketAddress:         128.111.221.123(pulse),9(discard)
                timeout:        45
        Receiver's instance variables:
                semaphore:      nil
                socketHandle:   nil
                readSemaphore:  nil
                writeSemaphore:         nil
                primitiveOnlySupportsOneSemaphore:      true

Socket>>connectTo:
        Receiver: a Socket[destroyed]
        Arguments and temporary variables:
                aSocketAddress:         128.111.221.123(pulse),9(discard)
        Receiver's instance variables:
                semaphore:      nil
                socketHandle:   nil
                readSemaphore:  nil
                writeSemaphore:         nil
                primitiveOnlySupportsOneSemaphore:      true

Socket>>connectTo:port:
        Receiver: a Socket[destroyed]
        Arguments and temporary variables:
                hostAddress:    128.111.221.123(pulse),9(discard)
                port:   9
        Receiver's instance variables:
                semaphore:      nil
                socketHandle:   nil
                readSemaphore:  nil
                writeSemaphore:         nil
                primitiveOnlySupportsOneSemaphore:      true

Socket class>>sendTest
        Receiver: Socket
        Arguments and temporary variables:
                sock:   a Socket[destroyed]
                bytesToSend:    nil
                sendBuf:        nil
                t:      nil
                serverName:     'create.ucsb.edu'
                serverAddr:     128.111.221.123(pulse),9(discard)
                bytesSent:      #(nil)
        Receiver's instance variables:
                superclass:     Object
                methodDict:     a MethodDictionary(size 137)
                format:         140
                instanceVariables:      #('semaphore' 'socketHandle' 
'readSemaphore'  
'writeSemaphore...etc...
                organization:   ('accessing' address localAddress localPort 
peerName  
port primiti...etc...
                subclasses:     {SocksSocket . HTTPSocket . RFBSocket}
                name:   #Socket
                classPool:      a Dictionary(#Connected->2 #DeadServer- 
 >'update.squeakfoundation.org...etc...
                sharedPools:    nil
                environment:    Smalltalk
                category:       #'Network-Kernel'
                traitComposition:       {}
                localSelectors:         nil

Socket class>>DoIt
        Receiver: Socket
        Arguments and temporary variables:

        Receiver's instance variables:
                superclass:     Object
                methodDict:     a MethodDictionary(size 137)
                format:         140
                instanceVariables:      #('semaphore' 'socketHandle' 
'readSemaphore'  
'writeSemaphore...etc...
                organization:   ('accessing' address localAddress localPort 
peerName  
port primiti...etc...
                subclasses:     {SocksSocket . HTTPSocket . RFBSocket}
                name:   #Socket
                classPool:      a Dictionary(#Connected->2 #DeadServer- 
 >'update.squeakfoundation.org...etc...
                sharedPools:    nil
                environment:    Smalltalk
                category:       #'Network-Kernel'
                traitComposition:       {}
                localSelectors:         nil


For cross check let's look at what happens before the closure code.

pre closure work
in a pharo0.1-10211dev09.01.3.image


(gdb) call (int) printAllStacks()
Process
545073376 Socket>initialize:
545073560 [] in >newTCP
545073284 BlockContext>repeatWithGCIf:
545072904 >newTCP
545072812 >new
544992420 >sendTest
544992328 >?
544989336 Compiler>evaluate:in:to:notifying:ifFail:logged:
544989004 [] in ParagraphEditor>evaluateSelection
544988912 BlockContext>on:do:
544988664 ParagraphEditor>evaluateSelection
544988572 ParagraphEditor>doIt

again

545075672  
Socket 
 > 
primSocketCreateNetwork:type:receiveBufferSize:sendBufSize:semaIndex:readSemaIndex:writeSemaIndex
 
:
545073376 Socket>initialize:
545073560 [] in >newTCP
545073284 BlockContext>repeatWithGCIf:
545072904 >newTCP
545072812 >new
544992420 >sendTest
544992328 >?
544989336 Compiler>evaluate:in:to:notifying:ifFail:logged:
544989004 [] in ParagraphEditor>evaluateSelection
544988912 BlockContext>on:do:
544988664 ParagraphEditor>evaluateSelection
544988572 ParagraphEditor>doIt

fullGC happens.

Process
545024744 SystemDictionary>garbageCollect
545024440 BlockContext>repeatWithGCIf:
545024336 >newTCP
545024244 >new
544992420 >sendTest
544992328 >?
544989336 Compiler>evaluate:in:to:notifying:ifFail:logged:
544989004 [] in ParagraphEditor>evaluateSelection
544988912 BlockContext>on:do:
544988664 ParagraphEditor>evaluateSelection
544988572 ParagraphEditor>doIt

off we go again to create socket.

Process
543469672 Socket>initialize:
543447120 [] in >newTCP
543447028 BlockContext>repeatWithGCIf:
543446924 >newTCP
543446832 >new
543438208 >sendTest
543438116 >?
543435124 Compiler>evaluate:in:to:notifying:ifFail:logged:
543434792 [] in ParagraphEditor>evaluateSelection
543434700 BlockContext>on:do:
543434452 ParagraphEditor>evaluateSelection
543434360 ParagraphEditor>doIt

off we go again to create socket.

Process
543471784  
Socket 
 > 
primSocketCreateNetwork:type:receiveBufferSize:sendBufSize:semaIndex:readSemaIndex:writeSemaIndex
 
:
543469672 Socket>initialize:
543447120 [] in >newTCP
543447028 BlockContext>repeatWithGCIf:
543446924 >newTCP
543446832 >new
543438208 >sendTest
543438116 >?
543435124 Compiler>evaluate:in:to:notifying:ifFail:logged:
543434792 [] in ParagraphEditor>evaluateSelection
543434700 BlockContext>on:do:
543434452 ParagraphEditor>evaluateSelection
543434360 ParagraphEditor>doIt


and end up with walkback at.

Socket status must Unconnected before opening a new connection


connectNonBlockingTo: hostAddress port: port
        "Initiate a connection to the given port at the given host address.  
This operation will return immediately; follow it with  
waitForConnectionUntil: to wait until the connection is established."

        | status |
        self initializeNetwork.
        status := self primSocketConnectionStatus: socketHandle.
        (status == Unconnected)
                ifFalse: [InvalidSocketStatusException signal: 'Socket status 
must  
Unconnected before opening a new connection'].




= 
= 
= 
========================================================================
John M. McIntosh <[email protected]>   Twitter:   
squeaker68882
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
= 
= 
= 
========================================================================





_______________________________________________
Pharo-project mailing list
[email protected]
http://lists.gforge.inria.fr/cgi-bin/mailman/listinfo/pharo-project

Reply via email to