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