2017-10-31 14:45:15 +00:00
|
|
|
#include 'Moo.moo'.
|
|
|
|
|
2017-10-18 16:15:51 +00:00
|
|
|
class Socket(Object) from 'sck'
|
|
|
|
{
|
|
|
|
var handle := -1.
|
2017-12-20 16:25:20 +00:00
|
|
|
var insem, outsem.
|
|
|
|
var(#get,#set) inputAction, outputAction.
|
2017-10-18 16:15:51 +00:00
|
|
|
|
2017-12-17 15:20:58 +00:00
|
|
|
method(#primitive) open(domain, type, proto).
|
2017-10-18 16:15:51 +00:00
|
|
|
method(#primitive) _close.
|
2017-12-17 15:20:58 +00:00
|
|
|
method(#primitive) connect(a,b,c).
|
2017-12-20 16:25:20 +00:00
|
|
|
method(#primitive) endConnect.
|
|
|
|
|
|
|
|
method(#primitive) readBytes: bytes.
|
|
|
|
method(#primitive) writeBytes: bytes.
|
2017-10-18 16:15:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
(* TODO: generate these domain and type from the C header *)
|
|
|
|
pooldic Socket.Domain
|
|
|
|
{
|
|
|
|
INET := 2.
|
|
|
|
INET6 := 10.
|
|
|
|
}
|
|
|
|
|
|
|
|
pooldic Socket.Type
|
|
|
|
{
|
|
|
|
STREAM := 1.
|
|
|
|
DGRAM := 2.
|
|
|
|
}
|
|
|
|
|
|
|
|
extend Socket
|
|
|
|
{
|
2017-10-30 01:11:18 +00:00
|
|
|
method(#class) new { self messageProhibited: #new }
|
|
|
|
method(#class) new: size { self messageProhibited: #new: }
|
|
|
|
|
|
|
|
method(#class) domain: domain type: type
|
|
|
|
{
|
2017-12-17 15:20:58 +00:00
|
|
|
^super new open(domain, type, 0).
|
2017-10-30 01:11:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
method close
|
2017-10-18 16:15:51 +00:00
|
|
|
{
|
2017-10-30 01:11:18 +00:00
|
|
|
if (self.handle >= 0)
|
|
|
|
{
|
|
|
|
## this primitive method may return failure.
|
2017-12-17 15:20:58 +00:00
|
|
|
## but ignore it here.
|
2017-12-20 16:25:20 +00:00
|
|
|
if (self.insem)
|
|
|
|
{
|
|
|
|
System unsignal: self.insem.
|
|
|
|
System removeAsyncSemaphore: self.insem.
|
|
|
|
self.insem := nil.
|
|
|
|
}.
|
|
|
|
if (self.outsem)
|
|
|
|
{
|
|
|
|
System unsignal: self.outsem.
|
|
|
|
System removeAsyncSemaphore: self.outsem.
|
|
|
|
self.outsem := nil.
|
|
|
|
}.
|
|
|
|
|
2017-10-30 01:11:18 +00:00
|
|
|
self _close.
|
|
|
|
self.handle := -1.
|
|
|
|
}
|
|
|
|
}
|
2017-10-18 16:15:51 +00:00
|
|
|
|
2017-10-30 01:11:18 +00:00
|
|
|
method asyncConnect: connectBlock
|
|
|
|
{
|
2017-12-17 15:38:38 +00:00
|
|
|
| s1 s2 sa |
|
2017-10-31 07:13:22 +00:00
|
|
|
|
2017-10-30 01:11:18 +00:00
|
|
|
s1 := Semaphore new.
|
|
|
|
s2 := Semaphore new.
|
2017-10-18 16:15:51 +00:00
|
|
|
|
2017-10-31 07:13:22 +00:00
|
|
|
sa := [:sem |
|
2017-11-05 16:47:13 +00:00
|
|
|
System unsignal: s1.
|
|
|
|
System unsignal: s2.
|
2017-12-20 16:25:20 +00:00
|
|
|
'UNSIGNALLLING ...........' dump.
|
2017-10-31 07:13:22 +00:00
|
|
|
System removeAsyncSemaphore: s1.
|
|
|
|
System removeAsyncSemaphore: s2.
|
2017-12-20 16:25:20 +00:00
|
|
|
|
|
|
|
'FINALIZING CONNECT' dump.
|
|
|
|
self endConnect.
|
|
|
|
connectBlock value: self value: (sem == s1)
|
2017-10-31 07:13:22 +00:00
|
|
|
].
|
|
|
|
|
|
|
|
s1 signalAction: sa.
|
|
|
|
s2 signalAction: sa.
|
2017-10-18 16:15:51 +00:00
|
|
|
|
2017-12-17 15:38:38 +00:00
|
|
|
[
|
|
|
|
System signal: s1 onOutput: self.handle.
|
|
|
|
System signal: s2 afterSecs: 10.
|
|
|
|
System addAsyncSemaphore: s1.
|
|
|
|
System addAsyncSemaphore: s2.
|
|
|
|
self connect(1, 2, 3).
|
|
|
|
] ifCurtailed: [
|
2017-12-18 13:34:47 +00:00
|
|
|
## rollback
|
2017-12-17 15:38:38 +00:00
|
|
|
sa value: s2.
|
|
|
|
]
|
2017-10-30 01:11:18 +00:00
|
|
|
}
|
|
|
|
|
2017-12-20 16:25:20 +00:00
|
|
|
method watchInput
|
2017-10-30 01:11:18 +00:00
|
|
|
{
|
2017-12-20 16:25:20 +00:00
|
|
|
if (self.insem isNil)
|
|
|
|
{
|
|
|
|
self.insem := Semaphore new.
|
|
|
|
self.insem signalAction: [:sem | self.inputAction value: self value: true].
|
|
|
|
System signal: self.insem onInput: self.handle.
|
|
|
|
System addAsyncSemaphore: self.insem.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
self.insem signalAction: [:sem | self.inputAction value: self value: true].
|
|
|
|
}
|
2017-10-18 16:15:51 +00:00
|
|
|
|
2017-12-20 16:25:20 +00:00
|
|
|
###s2 := Semaphore new.
|
|
|
|
###s2 signalAction: [:sem | inputActionBlock value: self value: false].
|
|
|
|
###System signal: s2 afterSecs: 10.
|
2017-10-18 16:15:51 +00:00
|
|
|
}
|
2017-10-30 01:11:18 +00:00
|
|
|
|
2017-12-20 16:25:20 +00:00
|
|
|
method unwatchInput
|
2017-10-30 01:11:18 +00:00
|
|
|
{
|
2017-12-20 16:25:20 +00:00
|
|
|
System unsignal: self.insem.
|
|
|
|
System removeAsyncSemaphore: self.insem.
|
|
|
|
}
|
2017-10-30 01:11:18 +00:00
|
|
|
|
2017-12-20 16:25:20 +00:00
|
|
|
method watchOutput
|
|
|
|
{
|
|
|
|
if (self.outsem isNil)
|
|
|
|
{
|
|
|
|
self.outsem := Semaphore new.
|
|
|
|
self.outsem signalAction: [:sem | self.outputAction value: self value: true].
|
|
|
|
System signal: self.outsem onOutput: self.handle.
|
|
|
|
System addAsyncSemaphore: self.outsem.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
self.outsem signalAction: [:sem | self.outputAction value: self value: true].
|
|
|
|
}
|
2017-10-30 01:11:18 +00:00
|
|
|
}
|
|
|
|
|
2017-12-20 16:25:20 +00:00
|
|
|
method unwatchOutput
|
|
|
|
{
|
|
|
|
System unsignal: self.outsem.
|
|
|
|
System removeAsyncSemaphore: self.outsem.
|
|
|
|
}
|
2017-10-18 16:15:51 +00:00
|
|
|
}
|
2017-10-30 01:11:18 +00:00
|
|
|
|
|
|
|
|
|
|
|
class MyObject(Object)
|
|
|
|
{
|
|
|
|
method(#class) main
|
|
|
|
{
|
2017-12-20 16:25:20 +00:00
|
|
|
| s conact inact outact |
|
|
|
|
|
|
|
|
inact := [:sck :state |
|
|
|
|
| data n |
|
|
|
|
|
|
|
|
data := ByteArray new: 100.
|
|
|
|
n := sck readBytes: data.
|
|
|
|
if (n == 0)
|
|
|
|
{
|
|
|
|
sck close.
|
|
|
|
}.
|
|
|
|
(n asString & ' bytes read') dump.
|
|
|
|
data dump.
|
|
|
|
].
|
|
|
|
|
|
|
|
outact := [:sck :state |
|
|
|
|
if (state)
|
|
|
|
{
|
2017-12-20 16:40:04 +00:00
|
|
|
sck writeBytes: #[ $h, $e, $l, $l, $o ].
|
2017-12-20 16:25:20 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
}
|
|
|
|
].
|
|
|
|
|
|
|
|
conact := [:sck :state |
|
|
|
|
if (state)
|
|
|
|
{
|
|
|
|
'CONNECTED NOW.............' dump.
|
|
|
|
##s onOutputDo: outact.
|
|
|
|
s writeBytes: #[ $h $e $l $l $o ].
|
|
|
|
s watchInput.
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
'UNABLE TO CONNECT............' dump.
|
|
|
|
}
|
|
|
|
].
|
|
|
|
|
|
|
|
## ------------------------------------------------------
|
|
|
|
|
2017-10-30 01:11:18 +00:00
|
|
|
[
|
|
|
|
s := Socket domain: Socket.Domain.INET type: Socket.Type.STREAM.
|
2017-12-20 16:25:20 +00:00
|
|
|
s inputAction: inact; outputAction: outact.
|
|
|
|
s asyncConnect: conact.
|
2017-10-30 01:11:18 +00:00
|
|
|
|
2017-10-31 14:45:15 +00:00
|
|
|
while (true)
|
|
|
|
{
|
|
|
|
System handleAsyncEvent.
|
|
|
|
}.
|
2017-10-30 01:11:18 +00:00
|
|
|
s close dump.
|
2017-12-20 16:25:20 +00:00
|
|
|
|
2017-10-30 01:11:18 +00:00
|
|
|
] on: Exception do: [:ex | ('Exception - ' & ex messageText) dump ].
|
|
|
|
|
|
|
|
'----- END OF MAIN ------' dump.
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|