1#include "RPCPendingCalls.h"
2#include <string.h>
3
4extern bool conf_no_check_ip_xid;
5
6extern void
7PendingCallInit(struct PendingCall *call)
8{
9	call->buffer=NULL;
10}
11
12extern void
13PendingCallDestroy(struct PendingCall *call)
14{
15	free (call->buffer);
16}
17
18extern void
19RPCPendingCallsInit(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
28extern void
29RPCPendingCallsDestroy(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
47extern struct PendingCall *
48RPCPendingCallsAddPendingCall (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
69extern struct PendingCall *
70RPCPendingCallsFindAndRemovePendingCall (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
108extern void
109SemaphorePoolInit(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
119extern void
120SemaphorePoolDestroy(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
132extern sem_id
133SemaphorePoolGet(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
162extern void
163SemaphorePoolPut(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