annotate Pml/Channels/ActivePmlChannel.cs @ 104:327be9216006

Improved PML code
author Ivo Smits <Ivo@UCIS.nl>
date Sat, 11 Oct 2014 14:05:41 +0200
parents 3ab940a0c7a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
1 ???using System;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
2 using UCIS.Pml;
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
3 using UCIS.Util;
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
4 using System.Collections.Generic;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
5 using System.Threading;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
6
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
7 namespace UCIS.Pml {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
8 public abstract class ActivePmlChannel : IPmlChannel {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
9 private ReadMessageAsyncResult _asyncWait = null;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
10 private Queue<PmlElement> _queue = new Queue<PmlElement>();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
11 private bool _isOpen = true;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
12
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
13 public virtual bool IsOpen { get { return _isOpen; } }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
14 public abstract void WriteMessage(PmlElement message);
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
15
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
16 public PmlElement ReadMessage() {
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
17 lock (_queue) {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
18 if (!IsOpen) throw new InvalidOperationException("The channel is not open");
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
19 while (_queue.Count == 0) {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
20 if (!IsOpen) throw new OperationCanceledException("The operation did not complete");
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
21 Monitor.Wait(_queue);
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
22 }
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
23 return _queue.Dequeue();
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
24 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
25 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
26
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
27 public IAsyncResult BeginReadMessage(AsyncCallback callback, object state) {
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
28 ReadMessageAsyncResult ar;
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
29 Boolean completed = false;
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
30 lock (_queue) {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
31 if (!IsOpen) throw new InvalidOperationException("The channel is not open");
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
32 if (_asyncWait != null) throw new InvalidOperationException("Another asynchronous operation is in progress");
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
33 ar = new ReadMessageAsyncResult(callback, state);
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
34 if (_queue.Count == 0) {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
35 _asyncWait = ar;
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
36 } else {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
37 ar.Message = _queue.Dequeue();
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
38 completed = true;
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
39 }
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
40 }
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
41 if (completed) ar.SetCompleted(true, null);
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
42 return ar;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
43 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
44
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
45 public PmlElement EndReadMessage(IAsyncResult asyncResult) {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
46 ReadMessageAsyncResult ar = (ReadMessageAsyncResult)asyncResult;
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
47 ar.WaitForCompletion();
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
48 if (ar.Error != null) throw new OperationCanceledException("The asynchronous operation failed", ar.Error);
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
49 return ar.Message;
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
50 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
51
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
52 public virtual void Close() {
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
53 ReadMessageAsyncResult asyncWait;
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
54 lock (_queue) {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
55 _isOpen = false;
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
56 asyncWait = Interlocked.Exchange<ReadMessageAsyncResult>(ref _asyncWait, null);
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
57 Monitor.PulseAll(_queue);
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
58 }
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
59 if (asyncWait != null) asyncWait.SetCompleted(false, new ObjectDisposedException("ActivePmlChannel"));
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
60 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
61
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
62 public void Dispose() {
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
63 Close();
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
64 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
65
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
66 protected void PushReceivedMessage(PmlElement message) {
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
67 ReadMessageAsyncResult asyncWait;
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
68 lock (_queue) {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
69 asyncWait = Interlocked.Exchange<ReadMessageAsyncResult>(ref _asyncWait, null);
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
70 if (asyncWait == null) {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
71 _queue.Enqueue(message);
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
72 Monitor.Pulse(_queue);
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
73 }
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
74 }
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
75 if (asyncWait != null) {
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
76 asyncWait.Message = message;
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
77 asyncWait.SetCompleted(false, null);
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
78 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
79 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
80
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
81 class ReadMessageAsyncResult : AsyncResultBase {
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
82 internal PmlElement Message;
104
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
83 public ReadMessageAsyncResult(AsyncCallback callback, Object state) : base(callback, state) { }
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
84 public void SetCompleted(Boolean synchronously, Exception error) {
327be9216006 Improved PML code
Ivo Smits <Ivo@UCIS.nl>
parents: 0
diff changeset
85 base.SetCompleted(synchronously, error);
0
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
86 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
87 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
88 }
3ab940a0c7a0 Initial commit
Ivo Smits <Ivo@UCIS.nl>
parents:
diff changeset
89 }