[squeak-dev] The Inbox: Network-ul.180.mcz
Levente Uzonyi
leves at caesar.elte.hu
Mon Aug 1 01:39:43 UTC 2016
Hi Chris,
I decide to move this to the Trunk because the feature freeze is here.
This should also help getting more feedback. :)
Levente
On Mon, 25 Jul 2016, Chris Muller wrote:
> Hi Levente, Magma's test cases can't seem to get to the end with
> this.. I haven't investigated yet..
>
> On Mon, Jul 25, 2016 at 2:40 PM, Levente Uzonyi <leves at caesar.elte.hu> wrote:
>> Hi All,
>>
>> This is something to test on all platforms before push. I've used it on
>> 64-bit linux without problems so far.
>>
>> Levente
>>
>>
>> On Mon, 25 Jul 2016, commits at source.squeak.org wrote:
>>
>>> Levente Uzonyi uploaded a new version of Network to project The Inbox:
>>> http://source.squeak.org/inbox/Network-ul.180.mcz
>>>
>>> ==================== Summary ====================
>>>
>>> Name: Network-ul.180
>>> Author: ul
>>> Time: 25 July 2016, 8:40:01.001452 pm
>>> UUID: 2f23a55c-fec5-41ac-95bd-6a8c2458be95
>>> Ancestors: Network-nice.179
>>>
>>> Socket changes:
>>> - fixed the comment of #isOtherEndConnected and #isThisEndConnected
>>> - do not slice the data (TCP) in the image in #sendData:. Let the VM, the
>>> kernel, the hardware deal with that.
>>> - use #isOtherEndConnected when receiving data, and #isThisEndConnected
>>> when sending data instead of #isConnected
>>> - move away from #milliseconds:since:, since we have a clock that won't
>>> roll over
>>>
>>> =============== Diff against Network-nice.179 ===============
>>>
>>> Item was changed:
>>> ----- Method: Socket>>closeAndDestroy: (in category 'connection
>>> open/close') -----
>>> closeAndDestroy: timeoutSeconds
>>> "First, try to close this connection gracefully. If the close
>>> attempt fails or times out, abort the connection. In either case, destroy
>>> the socket. Do nothing if the socket has already been destroyed (i.e., if
>>> its socketHandle is nil)."
>>>
>>> + socketHandle ifNil: [ ^self ].
>>> + self isThisEndConnected ifTrue: [
>>> + self close. "Close this end." ].
>>> + (self waitForDisconnectionFor: timeoutSeconds) ifFalse: [
>>> + "The other end has not closed the connect yet, so we will
>>> just abort it."
>>> + self primSocketAbortConnection: socketHandle ].
>>> + self destroy!
>>> - socketHandle ifNotNil: [
>>> - self isConnected ifTrue: [
>>> - self close. "close this end"
>>> - (self waitForDisconnectionFor:
>>> timeoutSeconds) ifFalse: [
>>> - "The other end didn't
>>> close so we just abort the connection"
>>> - self
>>> primSocketAbortConnection: socketHandle]].
>>> - self destroy].
>>> - !
>>>
>>> Item was changed:
>>> ----- Method: Socket>>discardReceivedData (in category 'receiving') -----
>>> discardReceivedData
>>> "Discard any data received up until now, and return the number of
>>> bytes discarded."
>>>
>>> | buf totalBytesDiscarded |
>>> buf := String new: 10000.
>>> totalBytesDiscarded := 0.
>>> + [self isOtherEndConnected and: [self dataAvailable]] whileTrue: [
>>> - [self isConnected and: [self dataAvailable]] whileTrue: [
>>> totalBytesDiscarded :=
>>> totalBytesDiscarded + (self receiveDataInto:
>>> buf)].
>>> ^ totalBytesDiscarded
>>> !
>>>
>>> Item was changed:
>>> ----- Method: Socket>>isOtherEndConnected (in category 'queries') -----
>>> isOtherEndConnected
>>> + "Return true if this socket is connected, or this end has closed
>>> the connection but not the other end, so we can still receive data."
>>> - "Return true if this socket is connected, or this end has closed
>>> the connection but not the other end, so we can still send data."
>>>
>>> | state |
>>> socketHandle ifNil: [ ^false ].
>>> (state := self primSocketConnectionStatus: socketHandle) ==
>>> Connected ifTrue: [ ^true ].
>>> ^state == ThisEndClosed
>>> !
>>>
>>> Item was changed:
>>> ----- Method: Socket>>isThisEndConnected (in category 'queries') -----
>>> isThisEndConnected
>>> + "Return true if this socket is connected, other the other end has
>>> closed the connection but not this end, so we can still send data."
>>> - "Return true if this socket is connected, other the other end has
>>> closed the connection but not this end, so we can still receive data."
>>>
>>> | state |
>>> socketHandle ifNil: [ ^false ].
>>> (state := self primSocketConnectionStatus: socketHandle) ==
>>> Connected ifTrue: [ ^true ].
>>> ^state == OtherEndClosed
>>> !
>>>
>>> Item was changed:
>>> ----- Method: Socket>>sendData: (in category 'sending') -----
>>> sendData: aStringOrByteArray
>>> "Send all of the data in the given array, even if it requires
>>> multiple calls to send it all. Return the number of bytes sent."
>>>
>>> "An experimental version use on slow lines: Longer timeout and
>>> smaller writes to try to avoid spurious timeouts."
>>>
>>> | bytesSent bytesToSend count |
>>> bytesToSend := aStringOrByteArray size.
>>> bytesSent := 0.
>>> [bytesSent < bytesToSend] whileTrue: [
>>> (self waitForSendDoneFor: 60)
>>> ifFalse: [ConnectionTimedOut signal: 'send data
>>> timeout; data not sent'].
>>> count := self primSocket: socketHandle
>>> sendData: aStringOrByteArray
>>> startIndex: bytesSent + 1
>>> + count: bytesToSend - bytesSent.
>>> - count: (bytesToSend - bytesSent min:
>>> DefaultSendBufferSize).
>>> bytesSent := bytesSent + count].
>>>
>>> ^ bytesSent
>>> !
>>>
>>> Item was changed:
>>> ----- Method: Socket>>waitForConnectionFor:ifTimedOut:ifRefused: (in
>>> category 'waiting') -----
>>> waitForConnectionFor: timeout ifTimedOut: timeoutBlock ifRefused:
>>> refusedBlock
>>> "Wait up until the given deadline for a connection to be
>>> established. Return true if it is established by the deadline, false if
>>> not."
>>>
>>> + | deadline timeLeft status |
>>> + deadline := Time millisecondClockValue + (timeout * 1000)
>>> truncated.
>>> + (status := self primSocketConnectionStatus: socketHandle) ==
>>> Connected ifTrue: [^true].
>>> + [ (status == WaitingForConnection) and: [ (timeLeft := deadline -
>>> Time millisecondClockValue) > 0 ] ]
>>> - | startTime msecsDelta msecsEllapsed status |
>>> - startTime := Time millisecondClockValue.
>>> - msecsDelta := (timeout * 1000) truncated.
>>> - status := self primSocketConnectionStatus: socketHandle.
>>> - status = Connected ifTrue: [^true].
>>> - [(status = WaitingForConnection) and: [(msecsEllapsed := Time
>>> millisecondsSince: startTime) < msecsDelta]]
>>> whileTrue: [
>>> + semaphore waitTimeoutMSecs: timeLeft.
>>> + status := self primSocketConnectionStatus:
>>> socketHandle ].
>>> + status == Connected ifTrue: [ ^true ].
>>> + status == WaitingForConnection
>>> + ifTrue: [ timeoutBlock value ]
>>> + ifFalse: [ refusedBlock value ].
>>> + ^false!
>>> - semaphore waitTimeoutMSecs: msecsDelta -
>>> msecsEllapsed.
>>> - status := self primSocketConnectionStatus:
>>> socketHandle].
>>> - status = Connected
>>> - ifFalse: [
>>> - status = WaitingForConnection
>>> - ifTrue: [timeoutBlock value]
>>> - ifFalse: [refusedBlock value].
>>> - ^false].
>>> - ^ true!
>>>
>>> Item was changed:
>>> ----- Method: Socket>>waitForConnectionUntil: (in category 'waiting')
>>> -----
>>> waitForConnectionUntil: deadline
>>> "Wait up until the given deadline for a connection to be
>>> established. Return true if it is established by the deadline, false if
>>> not."
>>>
>>> + | status timeLeft |
>>> - | status waitTime |
>>> [
>>> (status := self primSocketConnectionStatus: socketHandle)
>>> == Connected ifTrue: [ ^true ].
>>> status == WaitingForConnection ifFalse: [ ^false ].
>>> + (timeLeft := deadline - Time millisecondClockValue) <= 0
>>> ifTrue: [ ^false ].
>>> + semaphore waitTimeoutMSecs: timeLeft ] repeat!
>>> - (waitTime := deadline - Time millisecondClockValue) > 0
>>> ifFalse: [ ^false ].
>>> - semaphore waitTimeoutMSecs: waitTime ] repeat!
>>>
>>> Item was changed:
>>> ----- Method: Socket>>waitForDataFor:ifClosed:ifTimedOut: (in category
>>> 'waiting') -----
>>> waitForDataFor: timeout ifClosed: closedBlock ifTimedOut: timedOutBlock
>>> "Wait for the given nr of seconds for data to arrive."
>>>
>>> + | deadline timeLeft |
>>> - | startTime msecsDelta |
>>> socketHandle ifNil: [ ^closedBlock value ].
>>> + deadline := Time millisecondClockValue + (timeout * 1000)
>>> truncated.
>>> - startTime := Time millisecondClockValue.
>>> - msecsDelta := (timeout * 1000) truncated.
>>> [
>>> (self primSocketReceiveDataAvailable: socketHandle)
>>> ifTrue: [ ^self ].
>>> + self isOtherEndConnected ifFalse: [ ^closedBlock value ].
>>> + (timeLeft := deadline - Time millisecondClockValue) <= 0
>>> ifTrue: [ ^timedOutBlock value ].
>>> - self isConnected ifFalse: [ ^closedBlock value ].
>>> - (Time millisecondsSince: startTime) < msecsDelta ifFalse:
>>> [ ^timedOutBlock value ].
>>> "Providing a maximum for the time for waiting is a
>>> workaround for a VM bug which causes sockets waiting for data forever in
>>> some rare cases, because the semaphore doesn't get signaled. Remove the
>>> ""min: self class maximumReadSemaphoreWaitTimeout"" part when the bug is
>>> fixed."
>>> readSemaphore waitTimeoutMSecs:
>>> + (timeLeft min: self class
>>> maximumReadSemaphoreWaitTimeout) ] repeat!
>>> - (msecsDelta - (Time millisecondsSince: startTime)
>>> min: self class maximumReadSemaphoreWaitTimeout) ] repeat!
>>>
>>> Item was changed:
>>> ----- Method: Socket>>waitForDataIfClosed: (in category 'waiting') -----
>>> waitForDataIfClosed: closedBlock
>>> "Wait indefinitely for data to arrive. This method will block
>>> until
>>> data is available or the socket is closed."
>>>
>>> socketHandle ifNil: [ ^closedBlock value ].
>>> [
>>> (self primSocketReceiveDataAvailable: socketHandle)
>>> ifTrue: [ ^self ].
>>> + self isOtherEndConnected ifFalse: [ ^closedBlock value ].
>>> - self isConnected ifFalse: [ ^closedBlock value ].
>>> "ul 8/13/2014 21:16
>>> Providing a maximum for the time for waiting is a
>>> workaround for a VM bug which
>>> causes sockets waiting for data forever in some rare
>>> cases, because the semaphore
>>> doesn't get signaled. Replace the ""waitTimeoutMSecs:
>>> self class maximumReadSemaphoreWaitTimeout""
>>> part with ""wait"" when the bug is fixed."
>>> readSemaphore waitTimeoutMSecs: self class
>>> maximumReadSemaphoreWaitTimeout ] repeat!
>>>
>>> Item was changed:
>>> ----- Method: Socket>>waitForDisconnectionFor: (in category 'waiting')
>>> -----
>>> waitForDisconnectionFor: timeout
>>> "Wait for the given nr of seconds for the connection to be broken.
>>> Return true if it is broken by the deadline, false if not.
>>> The client should know the connection is really going to be closed
>>> (e.g., because he has called 'close' to send a close request to
>>> the other end)
>>> before calling this method."
>>>
>>> + | deadline |
>>> + deadline := Time millisecondClockValue + (timeout * 1000)
>>> truncated.
>>> + [ self isOtherEndConnected and: [ deadline - Time
>>> millisecondClockValue > 0 ] ]
>>> + whileTrue: [
>>> + self discardReceivedData.
>>> + "Providing a maximum for the time for waiting is a
>>> workaround for a VM bug which causes sockets waiting for data forever in
>>> some rare cases, because the semaphore doesn't get signaled. Remove the
>>> ""min: self class maximumReadSemaphoreWaitTimeout"" part when the bug is
>>> fixed."
>>> + readSemaphore waitTimeoutMSecs:
>>> + (deadline - Time millisecondClockValue
>>> min: self class maximumReadSemaphoreWaitTimeout) ].
>>> + ^self isOtherEndConnected!
>>> - | startTime msecsDelta status |
>>> - startTime := Time millisecondClockValue.
>>> - msecsDelta := (timeout * 1000) truncated.
>>> - status := self primSocketConnectionStatus: socketHandle.
>>> - [((status == Connected) or: [(status == ThisEndClosed)]) and:
>>> - [(Time millisecondsSince: startTime) < msecsDelta]] whileTrue: [
>>> - self discardReceivedData.
>>> - "Providing a maximum for the time for waiting is a
>>> workaround for a VM bug which causes sockets waiting for data forever in
>>> some rare cases, because the semaphore doesn't get signaled. Remove the
>>> ""min: self class maximumReadSemaphoreWaitTimeout"" part when the bug is
>>> fixed."
>>> - readSemaphore waitTimeoutMSecs:
>>> - (msecsDelta - (Time millisecondsSince: startTime)
>>> min: self class maximumReadSemaphoreWaitTimeout).
>>> - status := self primSocketConnectionStatus: socketHandle].
>>> - ^ status ~= Connected!
>>>
>>> Item was changed:
>>> ----- Method: Socket>>waitForSendDoneFor: (in category 'waiting') -----
>>> waitForSendDoneFor: timeout
>>> "Wait up until the given deadline for the current send operation
>>> to complete. Return true if it completes by the deadline, false if not."
>>>
>>> + | deadline timeleft |
>>> + deadline := Time millisecondClockValue + (timeout * 1000)
>>> truncated.
>>> - | startTime msecsDelta msecsEllapsed |
>>> - startTime := Time millisecondClockValue.
>>> - msecsDelta := (timeout * 1000) truncated.
>>> [
>>> (self primSocketSendDone: socketHandle) ifTrue: [ ^true ].
>>> + self isThisEndConnected ifFalse: [ ^false ].
>>> + (timeleft := deadline - Time millisecondClockValue) <= 0
>>> ifTrue: [ ^false ].
>>> + writeSemaphore waitTimeoutMSecs: timeleft ] repeat!
>>> - self isConnected ifFalse: [ ^false ].
>>> - (msecsEllapsed := Time millisecondsSince: startTime) <
>>> msecsDelta ifFalse: [ ^false ].
>>> - writeSemaphore waitTimeoutMSecs: msecsDelta -
>>> msecsEllapsed ] repeat!
>>>
>>>
>>>
>>
>
>
More information about the Squeak-dev
mailing list
|