xref: /haiku/src/add-ons/kernel/file_systems/nfs/RPCPendingCalls.c (revision caa76e0da19432dc4f5da86a53e720f9be296256)
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