01: package dalma.endpoints.irc;
02:
03: import dalma.Condition;
04: import dalma.spi.FiberSPI;
05:
06: import java.io.Serializable;
07: import java.util.LinkedList;
08: import java.util.List;
09:
10: /**
11: * Represents a "place" where the communication happens in IRC.
12: *
13: * Either {@link Channel} or {@link PrivateChat}.
14: *
15: * @author Kohsuke Kawaguchi
16: */
17: public abstract class Session implements Serializable {
18:
19: /**
20: * {@link IRCEndPoint} to which this {@link Session} belongs to.
21: */
22: protected final IRCEndPoint endpoint;
23:
24: /**
25: * If a conversation is blocking on the next message from this buddy.
26: */
27: private Condition<Message> condition;
28:
29: /**
30: * Messages that are received.
31: *
32: * Access is synchronized against {@code this}.
33: */
34: private final List<Message> msgs = new LinkedList<Message>();
35:
36: protected Session(IRCEndPoint endpoint) {
37: this .endpoint = endpoint;
38: }
39:
40: /**
41: * Sends a message to this {@link Session}.
42: */
43: public abstract void send(String message);
44:
45: /**
46: * Blocks until a message is received.
47: */
48: public synchronized Message waitForNextMessage() {
49: while (msgs.isEmpty())
50: // block until we get a new message
51: FiberSPI.currentFiber(true).suspend(new MessageCondition());
52:
53: return msgs.remove(0);
54: }
55:
56: /**
57: * Closes this session and stops receiving futher messages
58: * from this {@link Session}.
59: */
60: public abstract void close();
61:
62: /**
63: * Called when a new message is received from IRC.
64: */
65: protected final synchronized void onMessageReceived(Message msg) {
66: msgs.add(msg);
67: if (condition != null) {
68: condition.activate(msg);
69: condition = null;
70: }
71: }
72:
73: /**
74: * This object needs to be serializable as it's referenced from conversations,
75: * we serialize monikers so that they connect back to the running Session instance.
76: */
77: protected abstract Object writeReplace();
78:
79: private final class MessageCondition extends Condition<Message> {
80: public MessageCondition() {
81: }
82:
83: public void onParked() {
84: condition = this ;
85: }
86:
87: public void interrupt() {
88: assert condition == this ;
89: condition = null;
90: }
91:
92: public void onLoad() {
93: onParked();
94: }
95: }
96: }
|