> Hello,
> I've seen that only UnixAioPlugin uses it (at least of internal plugins)
> and that 'Unix' prefix
> doesn't really sound good to me :).
> So, does #signalSemaphoreWithIndex: work on Windows and other platforms?
The #signalSemaphoreWithIndex: method provides a general way to signal
a semaphore in the Squeak image from the VM. It works on any platform,
including of course Windows. This provides a very nice mechanism for a
Process in Squeak "wake up" when some external event happens.
If you look at UnixAioPlugin, you'll find that it's really a subclass
of AioPlugin, and that the an AioEventHandler (a class in OSProcess
that knows how to handle aio events) looks for primitives in the
plugin with moduleName 'AioPlugin'. It really does not know that it is
using the concrete implementation in UnixAioEventHandler.
The intent here is that when someone needs aio event handling for
Windows or for Risc OS, they will implement Win32AioPlugin or
RiscOSAioPlugin as subclasses of AioPlugin. When building AioPlugin
for Windows or RiscOS, VMMaker picks the right subclass to use, and
the result is an AioPlugin built with code generated from
Win32AioPlugin, RiscOSAioPlugin, or UnixAioPlugin depending on the
platform.
Anyway, back to your original question: #signalSemaphoreWithIndex: is
completely platform-independent and can be used on Windows or any
other OS.
Dave
> So, does #signalSemaphoreWithIndex: work on Windows and other
platforms?
Yes it does. It's a feature of the VM (the interpreter), and it's
100% platform independent. In fact, if there is no platform it also
works (we are using it in SqueakNOS).
David explained why you may want to use it. The counterpart is how
to use it:
In Squeak at some point you'll want to wait for an external event, for
this, you create a Semaphore and register it:
<code>
sem := Semaphore new.
plugin registerSemaphore: (Smalltalk registerExternalObject: sem).
</code>
With #registerExternalObject: you register the object so it can be
accessed from the native world. This is necesary because objects tend
to move with Garbage Collection, so if you just used a direct pointer
to the object, this pointer would become obsolete when the GC moves
the object. #registerExternalObject: puts the object in an array
(updated by the GC I guess) and returns an index.
your plugin will need to implement something like #registerSemaphore:,
for example for SqueakNOS we have:
<code>
SqueakNOSPlugin>>primitiveRegisterSemaphoreIndex: aSemaphoreIndex
forIRQ: irqNumber
| IRQSemaphores |
self primitive: 'primitiveRegisterSemaphoreIndexForIRQ'
parameters: #(SmallInteger SmallInteger).
self var: #IRQSemaphores type: 'extern t_IRQSemaphores'.
irqNumber < (IRQSemaphores sizeof/(IRQSemaphores at: 0) sizeof)
ifTrue: [IRQSemaphores at: irqNumber put: aSemaphoreIndex]
ifFalse: [interpreterProxy primitiveFail].
^ interpreterProxy trueObject
</code>
where t_IRQSemaphores is nothing more than an array of integers. So
we save the index returned by #registerExternalObject: in this array
for when we want to use it.
When the external even hapens (your native part will know), you need
to call #signalSemaphoreWithIndex:, for example:
<code>
void signalIRQ(int number) {
if (0 != IRQSemaphores[number])
signalSemaphoreWithIndex(IRQSemaphores[number]);
}
</code>
and inside Squeak you will have a Process waiting on the Semaphore,
for example, the complite code could be:
<code>
sem := Semaphore new.
self primRegisterSemaphore: (Smalltalk registerExternalObject: sem).
[[
sem wait.
self doSomething] repeat.
] fork.