[Q][Unix][Sockets] Looking for explainations of 3 semaphores and error states.

John M McIntosh johnmci at smalltalkconsulting.com
Thu Jul 20 04:05:31 UTC 2000


on 7/19/00 8:05 PM, Rob Withers at slosher2 at home.com wrote:

> Hi All,
> 
> I am digging into the sqUnixNetwork.c code to try and implement Accepts
> and so forth.  I am grabbing some stuff from the 2.7 impl and looking at
> the new Mac impl.  My main design question is what is the benefit of the
> three semaphore model?
> 
> I am also trying to implement a backlog queue for listening, and so I am
> looking at modifying the privateSocketStruct.  Are there still
> situations where we can miss connections?  How do those happen?
> 
> Finally, there are a whole slew of error states that these buggers can
> be in.  Does anyone have a list of those?
> 
> Any information is very welcome,
> Rob

Well I've some background information about why three on my web page

http://www.smalltalkconsulting.com/html/OTNotes1.html

Also I've some thoughts about programming patterns that could use three
semaphores. Mostly focused around a read thread, a write thread, and a
control thread for listen/accept/close/destroy for which I didn't want to
share a single or two semaphores in some manner between all three threads.

MMM error codes?, well some errors are thrown from C primitive code based on
exceptions about incoming parms, or setup issues. These can be the same
between dialect and of course should be, I doubt they are today. Other error
codes are specific to the hosting OS since they percolate upwards from the
OS routines but need to be passed upwards to Squeak so the fellow that is
trying to understand why the socket connection failed can at least somewhere
refer to the tcp/ip manual for his hosting OS and get an explanation about
what he is doing wrong.

Error states?

statusString
    "Return a string describing the status of this socket."

    | status |
    socketHandle == nil ifTrue: [^ 'destroyed'].
    status _ self primSocketConnectionStatus: socketHandle.
    status = InvalidSocket ifTrue: [^ 'invalidSocketHandle'].
    status = Unconnected ifTrue: [^ 'unconnected'].
    status = WaitingForConnection ifTrue: [^ 'waitingForConnection'].
    status = Connected ifTrue: [^ 'connected'].
    status = OtherEndClosed ifTrue: [^ 'otherEndClosedButNotThisEnd'].
    status = ThisEndClosed ifTrue: [^ 'thisEndClosedButNotOtherEnd'].
    ^ 'unknown socket status'

There is a priority in terms of how you resolve the status to the
primSocketConnectionStatus I took a stab at it with the mac primitive

static SInt32 unmapStatus(EPInfo *s) {
    if (OTAtomicTestBit(&s->stateFlags3, kSleepKilledMe))
        {return  InvalidSocket;
        }
    if (OTAtomicTestBit(&s->stateFlags, kThisEndClosed))
        {return  ThisEndClosed;
        }
    if (OTAtomicTestBit(&s->stateFlags, kOtherEndClosed))
        {return  OtherEndClosed;
        }
    if (OTAtomicTestBit(&s->stateFlags, kConnected))
        { return  Connected;
        }
    if (OTAtomicTestBit(&s->stateFlags, kWaitingForConnection))
        {return  WaitingForConnection;
        }
    if (OTAtomicTestBit(&s->stateFlags, kUnConnected))
        {return  Unconnected;
        }
   return 0;
}

Also in the mac primitive I've (MMM too many status sorry)
{
    kOpenInProgressBit                = 0,  // Opening the socket (setup)
    kUnConnected                    = 1,    // Socket is unconnected
    kWaitingForConnection           = 2,    // connection request is in
progress, or a listen is outstanding
    kConnected                      = 3,    // Connected
    kSendIsBlocked                  = 4,    // Sending data is blocked
    kOtherEndClosed                 = 5,    // Other side issued a half
close
    kThisEndClosed                  = 6,    // We issued a half close
    kPassconBit                     = 7     // House keeping for
listen/accept handshake, see OT manual

};

    // Bit numbers in EPInfo stateFlags2 fields
enum
{
    kFlushDisconnectInProgressBit    = 0,   //Flushing socket in progress
    kMakeEPIdle                     = 1,    // Internal logic
    kEPIsBroken                     = 2,   // Internal logic
    kReadFlowControl                = 3,  //Ability to read was blocked
    kPassconNeeded                  = 4,  // House keeping for listen/accept
handshake, see OT manual
    kTapSemaphore                   = 5,  //Tap the
open/close/listen/accept/connect semaphore when we need to.
    kTapSemaphoreReadData           = 6,  //Tap the read semaphore when we
need to
    kTapSemaphoreWriteData          = 7   //Tape the write semaphore when we
need to
};

    // Bit numbers in EPInfo stateFlags3 fields
enum
{
    kKeepAliveOptionNeeded          = 0,  //Housekeeping to remember to set
keepalive
    kSleepKilledMe                  = 1   //Internal to remember sleep
destruction.
}; 


--
===========================================================================
John M. McIntosh <johnmci at smalltalkconsulting.com> 1-800-477-2659
Corporate Smalltalk Consulting Ltd.  http://www.smalltalkconsulting.com
===========================================================================
Custom Macintosh programming & various Smalltalk dialects
PGP Key: DSS/Diff/46FC3BE6
Fingerprint=B22F 7D67 92B7 5D52 72D7  E94A EE69 2D21 46FC 3BE6
===========================================================================





More information about the Squeak-dev mailing list