1 using System;
 2 using System.Collections;
 3 
 4 namespace cmsx.kernel
 5 {
 6     public const long numSessionSlots = 128;
 7 
 8     public class Session
 9     {
10         public nothrow Session() : sid(-1)nextFree(null)fgpid(-1)
11         {
12         }
13         public nothrow Session(int sid_) : sid(sid_)nextFree(null)fgpid(-1)
14         {
15         }
16         public int sid;
17         public int fgpid;
18         public Session* nextFree;
19     }
20 
21     public class SessionTable
22     {
23         static SessionTable() : instance(new SessionTable())
24         {
25         }
26         public static SessionTable& Instance()
27         {
28             return *instance;
29         }
30         private nothrow SessionTable() : nextFreeSessionSlot(0)nextSid(0)free(null)
31         {
32         }
33         public Session* CreateSession()
34         {
35             Session* session = null;
36             if (free != null)
37             {
38                 session = free;
39                 free = free->nextFree;
40             }
41             else if (nextFreeSessionSlot < numSessionSlots)
42             {
43                 session = &sessions[nextFreeSessionSlot++];
44             }
45             else
46             {
47                 throw SystemError(ERLIMITEXCEEDED"maximum number of open sessions (" + ToString(numSessionSlots) + ") exceeeded");
48             }
49             session->sid = nextSid++;
50             session->nextFree = null;
51             sessionMap[session->sid] = session;
52             return session;
53         }
54         public void FreeSession(Session* session)
55         {
56             sessionMap.Remove(session->sid);
57             session->nextFree = free;
58             session->sid = -1;
59             free = session;
60         }
61         public Session* GetSession(int sid) const
62         {
63             HashMap<intSession*>.ConstIterator it = sessionMap.CFind(sid);
64             if (it != sessionMap.CEnd())
65             {
66                 return it->second;
67             }
68             else
69             {
70                 throw SystemError(EINVAL"invalid session identifier");
71             }
72         }
73         private static UniquePtr<SessionTable> instance;
74         private int nextFreeSessionSlot;
75         private int nextSid;
76         private Session[numSessionSlots] sessions;
77         private HashMap<intSession*> sessionMap;
78         private Session* free;
79     }
80 
81     public SessionTable& GetSessionTable()
82     {
83         return SessionTable.Instance();
84     }
85 }
86