05.08.2014 Views

here - Stefan-Marr.de

here - Stefan-Marr.de

here - Stefan-Marr.de

SHOW MORE
SHOW LESS

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

5. An Ownership-based MOP for Expressing Concurrency Abstractions<br />

1 Agent = (<br />

2 | state mailbox immutDomain |<br />

3<br />

4 read = unenforced ( ^ state )<br />

5<br />

6 " update blocks are of the form :<br />

7 [: oldState | oldState produceNewState ]"<br />

8 send : anUpdateBlock = unenforced (<br />

9 mailbox nextPut : anUpdateBlock )<br />

10<br />

11 initialize = unenforced (<br />

12 | domain |<br />

13 mailbox := SharedQueue new .<br />

14 immutDomain := ImmutableDomain new .<br />

15 domain := AgentDomain new agent : self .<br />

16 domain spawnHere : [<br />

17 true whileTrue : [ self processUpdateBlock ]]. )<br />

18<br />

19 processUpdateBlock = (<br />

20 | updateBlock newState |<br />

21 updateBlock := mailbox waitForFirst .<br />

22 newState := domain evaluateEnforced : [<br />

23 updateBlock value : state ].<br />

24 state := immutDomain adopt : newState .<br />

25 mailbox removeFirst . ) )<br />

Listing 5.2: Clojure agents implemented in SOM Smalltalk<br />

For the purpose of this discussion, agents are represented by an object that<br />

has the field state to represent the state of the agent and the field mailbox,<br />

which holds incoming update requests. In addition to the object itself, an<br />

agent has an associated Process, i. e., thread, which evaluates the incoming<br />

update requests one by one. The mailbox is a SharedQueue object, i. e.,<br />

a concurrent queue data structure. The queue implements #waitForFirst to<br />

block the current thread until the queue has at least one element and then<br />

return the element without removing it. This operation is complemented by<br />

#removeFirst, which removes the first element of the queue.<br />

The example uses these operations to implement the basic methods of the<br />

agent. Thus, #read returns the current state and #send: enqueues an update<br />

request for the agent’s state. The request is represented by anUpdateBlock,<br />

which is a lambda, i. e., a block, with a single argument. The argument is the<br />

old state, which is going to be replaced by the result the block returns.<br />

122

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!