1 #include "RPCPendingCalls.h"
2 #include <string.h>
3
4 extern bool conf_no_check_ip_xid;
5
6 extern void
PendingCallInit(struct PendingCall * call)7 PendingCallInit(struct PendingCall *call)
8 {
9 call->buffer=NULL;
10 }
11
12 extern void
PendingCallDestroy(struct PendingCall * call)13 PendingCallDestroy(struct PendingCall *call)
14 {
15 free (call->buffer);
16 }
17
18 extern void
RPCPendingCallsInit(struct RPCPendingCalls * calls)19 RPCPendingCallsInit(struct RPCPendingCalls *calls)
20 {
21 SemaphorePoolInit(&calls->fPool);
22
23 calls->fFirst=NULL;
24 calls->fSem=create_sem(1,"RPCPendingCalls");
25 set_sem_owner (calls->fSem,B_SYSTEM_TEAM);
26 }
27
28 extern void
RPCPendingCallsDestroy(struct RPCPendingCalls * calls)29 RPCPendingCallsDestroy(struct RPCPendingCalls *calls)
30 {
31 delete_sem(calls->fSem);
32
33 while (calls->fFirst)
34 {
35 struct PendingCall *next=calls->fFirst->next;
36
37 SemaphorePoolPut (&calls->fPool,calls->fFirst->sem);
38 PendingCallDestroy (calls->fFirst);
39 free (calls->fFirst);
40
41 calls->fFirst=next;
42 }
43
44 SemaphorePoolDestroy (&calls->fPool);
45 }
46
47 extern struct PendingCall *
RPCPendingCallsAddPendingCall(struct RPCPendingCalls * calls,int32 xid,const struct sockaddr_in * addr)48 RPCPendingCallsAddPendingCall (struct RPCPendingCalls *calls,
49 int32 xid, const struct sockaddr_in *addr)
50 {
51 struct PendingCall *call=(struct PendingCall *)malloc(sizeof(struct PendingCall));
52 PendingCallInit (call);
53
54 call->sem=SemaphorePoolGet(&calls->fPool);
55
56 memcpy(&call->addr,addr,sizeof(struct sockaddr_in));
57 call->xid=xid;
58
59 while (acquire_sem (calls->fSem)==B_INTERRUPTED);
60
61 call->next=calls->fFirst;
62 calls->fFirst=call;
63
64 while (release_sem (calls->fSem)==B_INTERRUPTED);
65
66 return call;
67 }
68
69 extern struct PendingCall *
RPCPendingCallsFindAndRemovePendingCall(struct RPCPendingCalls * calls,int32 xid,const struct sockaddr_in * addr)70 RPCPendingCallsFindAndRemovePendingCall (struct RPCPendingCalls *calls,
71 int32 xid, const struct sockaddr_in *addr)
72 {
73 struct PendingCall *last=NULL;
74 struct PendingCall *current;
75
76 while (acquire_sem (calls->fSem)==B_INTERRUPTED);
77
78 current=calls->fFirst; // mmu_man
79
80 while (current)
81 {
82 if (current->xid==xid)
83 {
84 if (((current->addr.sin_addr.s_addr==addr->sin_addr.s_addr)&&
85 (current->addr.sin_port==addr->sin_port)) || conf_no_check_ip_xid)
86 {
87 if (last)
88 last->next=current->next;
89 else
90 calls->fFirst=current->next;
91
92 current->next=NULL;
93
94 while (release_sem (calls->fSem)==B_INTERRUPTED);
95 return current;
96 }
97 }
98
99 last=current;
100 current=current->next;
101 }
102
103 while (release_sem (calls->fSem)==B_INTERRUPTED);
104
105 return NULL;
106 }
107
108 extern void
SemaphorePoolInit(struct SemaphorePool * pool)109 SemaphorePoolInit(struct SemaphorePool *pool)
110 {
111 pool->fPool=NULL;
112 pool->fPoolCount=0;
113 pool->fPoolSize=0;
114
115 pool->fPoolSem=create_sem(1,"semaphore_pool_sem");
116 set_sem_owner (pool->fPoolSem,B_SYSTEM_TEAM);
117 }
118
119 extern void
SemaphorePoolDestroy(struct SemaphorePool * pool)120 SemaphorePoolDestroy(struct SemaphorePool *pool)
121 {
122 int32 i;
123
124 for (i=0;i<pool->fPoolCount;i++)
125 delete_sem (pool->fPool[i]);
126
127 free (pool->fPool);
128
129 delete_sem (pool->fPoolSem);
130 }
131
132 extern sem_id
SemaphorePoolGet(struct SemaphorePool * pool)133 SemaphorePoolGet(struct SemaphorePool *pool)
134 {
135 sem_id sem;
136
137 while (acquire_sem(pool->fPoolSem)==B_INTERRUPTED)
138 {
139 }
140
141 if (pool->fPoolCount==0)
142 {
143 sem=create_sem (0,"pending_call");
144
145 while (release_sem(pool->fPoolSem)==B_INTERRUPTED)
146 {
147 }
148
149 return sem;
150 }
151
152 sem=pool->fPool[pool->fPoolCount-1];
153 pool->fPoolCount--;
154
155 while (release_sem(pool->fPoolSem)==B_INTERRUPTED)
156 {
157 }
158
159 return sem;
160 }
161
162 extern void
SemaphorePoolPut(struct SemaphorePool * pool,sem_id sem)163 SemaphorePoolPut(struct SemaphorePool *pool, sem_id sem)
164 {
165 while (acquire_sem(pool->fPoolSem)==B_INTERRUPTED)
166 {
167 }
168
169 if (pool->fPoolCount+1>pool->fPoolSize)
170 {
171 pool->fPoolSize+=8;
172 pool->fPool=(sem_id *)realloc(pool->fPool,pool->fPoolSize*sizeof(sem_id));
173 }
174
175 pool->fPool[pool->fPoolCount]=sem;
176 pool->fPoolCount++;
177
178 while (release_sem(pool->fPoolSem)==B_INTERRUPTED)
179 {
180 }
181 }
182
183