OSDN Git Service

*** empty log message ***
[drdeamon64/drdeamon64.git] / deamon / drd64_server_recvstatus.c
1 /*DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64
2
3                          D r . D e a m o n  6 4
4                         for INTEL64(R), AMD64(R)
5         
6    Copyright(C) 2007-2009 Koine Yuusuke(koinec). All rights reserved.
7
8 Redistribution and use in source and binary forms, with or without
9 modification, are permitted provided that the following conditions are met:
10
11  1. Redistributions of source code must retain the above copyright notice,
12     this list of conditions and the following disclaimer.
13  2. Redistributions in binary form must reproduce the above copyright
14     notice, this list of conditions and the following disclaimer in the
15     documentation and/or other materials provided with the distribution.
16
17 THIS SOFTWARE IS PROVIDED BY Koine Yuusuke(koinec) ``AS IS'' AND ANY
18 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
19 WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
20 DISCLAIMED. IN NO EVENT SHALL Koine Yuusuke(koinec) OR CONTRIBUTORS BE
21 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
27 OF THE POSSIBILITY OF SUCH DAMAGE.
28
29 DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64DrDeAmOn64*/
30
31 /* File Info -----------------------------------------------------------
32 File: drd64_.c
33 Function: 
34 Comment: 
35 ----------------------------------------------------------------------*/
36
37 #include"drd64_server.h"
38 #define DRD64_SRC_SERVER_RECVSTATUS
39 #include"drd64_server_recvstatus.h"
40
41 Drd64_Server_RecvStatus         **gpp_recvstat;
42 Drd64_Server_RecvStatus         *gp_recvalloc;
43 int                                                     gi_recvalloc_max;
44 int                                                     gi_recvalloc_now;
45 int                                                     gi_recvstat_max;
46 Drd64_Server_RecvStatus         *gp_recv_resume_start;
47 Drd64_Server_RecvStatus         *gp_recv_resume_end;
48 int                                                     gi_recv_resume_max;
49 Drd64_Server_RecvStatus         *gp_recv_sockets_start;
50 Drd64_Server_RecvStatus         *gp_recv_sockets_end;
51
52
53 int
54         Drd64_Server_RecvStatus_FreeRecvStatus_All(
55                 void )
56 {
57         int             i_cnt;
58
59         for( i_cnt = 0; i_cnt < gi_recvalloc_max; i_cnt++ )     {
60                         free( (gp_recvalloc + i_cnt)->pv_buf );
61                         (gp_recvalloc + i_cnt)->pv_buf  = NULL;
62         }
63
64         free( gp_recvalloc );
65         gi_recvalloc_max        = 0;
66         gi_recvalloc_now        = 0;
67         gp_recvalloc            = NULL;
68
69         free( gpp_recvstat );
70         gpp_recvstat            = NULL;
71
72         return 0x00;
73 }
74
75
76 Drd64_Server_RecvStatus *
77         Drd64_Server_RecvStatus_AllocRecvStatus_Unit(
78                 int             i_alloc_units )
79 {
80         int             i_cnt;
81         int             i_init_start_id;
82         int             i_init_end_id;
83         void    *pv_temp;
84         Drd64_Server_RecvStatus         *p_recvs;
85
86         p_recvs = NULL;
87
88         if( 0 == gi_recvalloc_max )     {
89                 p_recvs = (Drd64_Server_RecvStatus *)malloc(
90                                                 sizeof( Drd64_Server_RecvStatus )
91                                                         * i_alloc_units );
92
93                 i_init_start_id         = 0;
94                 i_init_end_id           = i_alloc_units;
95         }
96         else    {
97                 p_recvs = realloc( gp_recvalloc,
98                                         gi_recvalloc_max + i_alloc_units );
99
100                 i_init_start_id         = gi_recvalloc_max;
101                 i_init_end_id           = gi_recvalloc_max + i_alloc_units;
102         }
103         
104         if( NULL == p_recvs )   {
105                 return NULL;
106         }
107
108
109         for( i_cnt = i_init_start_id; i_cnt < i_init_end_id; i_cnt++ )  {
110                 memset( (p_recvs + i_cnt), 0x00, 
111                                         sizeof( Drd64_Server_RecvStatus ) );
112                 (p_recvs + i_cnt)->i_recvstatus_id      = -1;
113                 (p_recvs + i_cnt)->i_fds_id                     = -1;
114
115                 pv_temp = malloc( DRD64_MAX_PACKET_LENGTH );
116                 if( NULL == pv_temp )   { break; }
117                 (p_recvs + i_cnt)->pv_buf               = pv_temp;
118                 gi_recvalloc_max++;
119         }
120
121         if( gi_recvalloc_max == i_init_start_id )       {
122                 return NULL;
123         }
124
125         gp_recvalloc    = p_recvs;
126         return p_recvs;
127 }
128
129
130 EXTERN_SERVER_RECVSTATUS
131 int
132         Drd64_Server_RecvStatus_Init(
133                 int i_alloc_units )
134 {
135         Drd64_Server_RecvStatus *p_recvs;
136
137         /* Alloc RecvStatus Struct Management Area --- */
138         gpp_recvstat
139                 = (Drd64_Server_RecvStatus **)malloc(
140                                         sizeof( Drd64_Server_RecvStatus *)
141                                                 * FD_SETSIZE * DRD64_PACKET_MAX_MULTIPLE);
142         if( NULL == gpp_recvstat )      { return 0x01; }
143
144         memset( gpp_recvstat, 0x00, 
145                                         sizeof( Drd64_Server_RecvStatus *)
146                                                 * FD_SETSIZE * DRD64_PACKET_MAX_MULTIPLE );
147
148         gi_recvstat_max = 0;
149         
150         /* Alloc RecvStatus Area ( with Packet Data buffer ) ---*/
151         p_recvs = Drd64_Server_RecvStatus_AllocRecvStatus_Unit( i_alloc_units );
152         if( NULL == p_recvs )   {
153                 Drd64_Server_RecvStatus_FreeRecvStatus_All();
154                 return 0x02;
155         }
156
157         gp_recvalloc    = p_recvs;
158         gi_recvalloc_now        = 0;
159
160         gp_recv_resume_start    = NULL;
161         gi_recv_resume_max              = FD_SETSIZE;
162
163         gp_recv_sockets_start   = NULL;
164         gp_recv_sockets_end             = NULL;
165
166         return 0x00;
167 }
168
169
170 EXTERN_SERVER_RECVSTATUS
171 int
172         Drd64_Server_RecvStatus_Term(
173                 void )
174 {
175         Drd64_Server_RecvStatus_FreeRecvStatus_All();
176
177         return 0x00;
178 }
179
180
181 EXTERN_SERVER_RECVSTATUS
182 Drd64_Server_RecvStatus *
183         Drd64_Server_RecvStatus_AllocRecvStatus(
184                 int     i_fds,
185                 int     i_alloc_units )
186 {
187         int             i_cnt;
188         Drd64_Server_RecvStatus         *p_recv;
189         Drd64_Server_RecvStatus         *p_temp;
190
191         p_recv  = NULL;
192
193         /* Check No-Use RecvStatus --- */
194         if( gi_recvalloc_now >= gi_recvalloc_max )      {
195                 /* Search No-Use RecvStatus --- */
196                 for( i_cnt = 0; i_cnt < gi_recvalloc_max; i_cnt++ )             {
197                         if( -1 == (gp_recvalloc + i_cnt)->i_recvstatus_id )     {
198                                 p_recv  = (gp_recvalloc + i_cnt);
199                                 break;
200                         }
201                 }
202
203                 /* Realloc RecvStatus --- */
204                 if( NULL == p_recv )    {
205                         p_temp
206                                 = Drd64_Server_RecvStatus_AllocRecvStatus_Unit(
207                                                 i_alloc_units );
208                         if( NULL == p_temp )    { return NULL; }
209
210                         gp_recvalloc    = p_temp;
211                         p_recv  = gp_recvalloc + gi_recvalloc_now++;
212                 }
213         }
214         else    {
215                 p_recv  = gp_recvalloc + gi_recvalloc_now++;
216         }
217
218         /* Set RecvStatus Init. Param ---*/
219         p_recv->i_recvstatus_id = i_fds;
220         p_recv->i_fds_id                = i_fds;
221         *(gpp_recvstat + i_fds) = p_recv;
222
223
224
225         if( i_fds + 1 > gi_recvstat_max )
226                 { gi_recvstat_max       = i_fds + 1; }
227
228         return p_recv;
229 }
230
231
232 void
233         Drd64_Server_RecvStatus_FreeRecvStatus(
234                 Drd64_Server_RecvStatus *p_recv )
235 {
236         assert( NULL != p_recv );
237
238         p_recv->pv_recv_before          = NULL;
239         p_recv->pv_recv_next            = NULL;
240         
241         p_recv->i_recvstatus_id         = -1;
242         p_recv->i_fds_id                        = -1;
243
244         return;
245 }
246
247
248 EXTERN_SERVER_RECVSTATUS
249 void
250         Drd64_Server_RecvStatus_CloseRecvStatus(
251                 int i_fds )
252 {
253         int             i_cnt;
254         Drd64_Server_RecvStatus *p_recv_now;
255         Drd64_Server_RecvStatus *p_recv_temp;
256
257         p_recv_now      = *(gpp_recvstat + i_fds);
258
259         if( NULL != p_recv_now )        {
260                 *(gpp_recvstat + i_fds) = NULL;
261
262                 if( i_fds + 1 == gi_recvstat_max )      {
263                         for( i_cnt = i_fds+1; i_cnt > 0; i_cnt-- )              {
264                                 p_recv_temp     = *(gpp_recvstat + i_cnt);
265                                 if( NULL != p_recv_temp )       {
266                                         gi_recvstat_max = i_cnt + 1;
267                                         break;
268                                 }
269                         }
270
271                         if( 0 == i_cnt ) { gi_recvstat_max      = 0; }
272                 }
273
274                 Drd64_Server_RecvStatus_FreeRecvStatus( p_recv_now );
275         }
276         
277         return;
278 }
279
280
281 EXTERN_SERVER_RECVSTATUS
282 int
283         Drd64_Server_RecvStatus_PushResumeChain(
284                 int             i_fds,
285                 int             i_alloc_units )
286 {
287         int             i_cnt;
288         int             i_recv_id;
289         Drd64_Server_RecvStatus         *p_recv_self;
290         Drd64_Server_RecvStatus         *p_recv_new;
291         Drd64_Server_RecvStatus         *p_recv_before;
292
293         i_recv_id       = -1;
294
295         /* Get Self RecvStatus --- */
296         p_recv_self     = *(gpp_recvstat + i_fds);
297         if( NULL == p_recv_self )       {
298                 return -1;
299         }
300
301         /* Get New RecvStatus --- */
302         p_recv_new
303                 = Drd64_Server_RecvStatus_AllocRecvStatus(
304                                         i_fds, i_alloc_units );
305         if( NULL == p_recv_new )        {
306                 return -2;
307         }
308
309         /* Push & Chain RecvStatus ---*/
310         /* new */
311         if( NULL == gp_recv_resume_start )      {
312                 gp_recv_resume_start            = p_recv_self;
313                 gp_recv_resume_end                      = p_recv_self;
314                 p_recv_self->pv_recv_before     = NULL;
315                 p_recv_self->pv_recv_next       = NULL;
316                 i_cnt = gi_recv_resume_max;
317         }
318         else    {
319                 i_cnt   = FD_SETSIZE;
320                 while(( NULL != *(gpp_recvstat + i_cnt) )
321                                         && ( i_cnt < gi_recv_resume_max ))      { i_cnt++; }
322                 assert( NULL == *(gpp_recvstat + i_cnt) );
323                 
324                 p_recv_before   = gp_recv_resume_end;
325                 assert( NULL != p_recv_before );
326                 
327                 p_recv_self->pv_recv_before     = (void *)p_recv_before;
328                 p_recv_self->pv_recv_next       = (void *)p_recv_before->pv_recv_next;
329                 p_recv_before->pv_recv_next     = (void *)p_recv_self;
330                 gp_recv_resume_end                      = p_recv_self;
331                 puts("push multi");
332         }
333
334         i_recv_id       = i_cnt;
335         p_recv_self->i_recvstatus_id    = i_cnt;
336         *(gpp_recvstat + p_recv_self->i_recvstatus_id)  = p_recv_self;
337         if( gi_recv_resume_max == i_cnt )       {
338                 gi_recv_resume_max++;
339         }
340         printf(" Push: %d\n", i_cnt );
341         
342         return i_recv_id;
343 }
344
345
346 EXTERN_SERVER_RECVSTATUS
347 int
348         Drd64_Server_RecvStatus_DeleteResumeChain(
349                 int             i_recv_id )
350 {
351         Drd64_Server_RecvStatus *p_recv_self;
352         Drd64_Server_RecvStatus *p_recv_before;
353         Drd64_Server_RecvStatus *p_recv_next;
354
355
356         p_recv_self     = *(gpp_recvstat + i_recv_id);
357         if( NULL == p_recv_self )       {
358                 return 0x01;
359         }       
360
361         p_recv_before   = (Drd64_Server_RecvStatus *)p_recv_self->pv_recv_before;
362         p_recv_next             = (Drd64_Server_RecvStatus *)p_recv_self->pv_recv_next;
363
364         if( NULL != p_recv_before )     {
365                 p_recv_before->pv_recv_next     = (void *)p_recv_next;
366         }
367
368         if( NULL != p_recv_next )       {
369                 p_recv_next->pv_recv_before     = (void *)p_recv_before;
370         }
371
372         if( p_recv_self->i_recvstatus_id == (gi_recv_resume_max - 1) )  {
373                 gi_recv_resume_max--;
374         }
375
376         if( FD_SETSIZE == gi_recv_resume_max )  {
377                 gp_recv_resume_start    = NULL;
378                 gp_recv_resume_end              = NULL;
379         }
380
381         *(gpp_recvstat + i_recv_id)             = NULL;
382
383         printf(" delete: %d (before=%p, next=%p)\n", i_recv_id, p_recv_before, p_recv_next );
384
385         Drd64_Server_RecvStatus_FreeRecvStatus( p_recv_self );
386
387         return 0x00;
388 }
389
390
391 EXTERN_SERVER_RECVSTATUS
392 int
393         Drd64_Server_RecvStatus_AddSocketsChain(
394                 Drd64_Server_RecvStatus *p_recv )
395 {
396         Drd64_Server_RecvStatus *p_before;
397
398         if( NULL == p_recv )    { return 0x01; }
399
400         p_before        = gp_recv_sockets_end;
401         
402         p_recv->pv_recv_before  = (void *)p_before;
403         if( NULL != p_before )
404                 { p_before->pv_recv_next        = (void *)p_recv; }
405         else
406                 { gp_recv_sockets_start = p_recv; }
407
408         gp_recv_sockets_end             = p_recv;
409         
410         return 0x00;
411 }
412
413
414 EXTERN_SERVER_RECVSTATUS
415 int
416         Drd64_Server_RecvStatus_DeleteSocketsChain(
417                 Drd64_Server_RecvStatus *p_recv )
418 {
419         Drd64_Server_RecvStatus *p_before;
420         Drd64_Server_RecvStatus *p_next;
421
422         if( NULL == p_recv )    { return -1; }
423
424         p_before        = (Drd64_Server_RecvStatus *)p_recv->pv_recv_before;
425         p_next          = (Drd64_Server_RecvStatus *)p_recv->pv_recv_next;
426
427         if( NULL != p_before )
428                 { p_before->pv_recv_next        = (void *)p_next; }
429         if( NULL != p_next )
430                 { p_next->pv_recv_before        = (void *)p_before; }
431
432         if( p_recv == gp_recv_sockets_start )
433                 { gp_recv_sockets_start = p_next; }     
434         if( p_recv == gp_recv_sockets_end )
435                 { gp_recv_sockets_end   = p_before; }
436
437         p_recv->pv_recv_next    = NULL;
438         p_recv->pv_recv_before  = NULL;
439         
440         return 0x00;
441 }
442
443
444 EXTERN_SERVER_RECVSTATUS
445 void
446         Drd64_Server_RecvStatus_InitRecvStatus(
447                 Drd64_Server_RecvStatus *p_recv,
448                 int     i_socket )
449 {
450         assert( NULL != p_recv );
451
452         p_recv->i_read_phase    = DRD64_SERVER_RECVSTATUS_PHASE_HEADER;
453         p_recv->b_recv_status   = DRD64_SERVER_RECVSTATUS_STATUS_READ;
454         p_recv->i_remain_bytes  = sizeof( Drd64_PacketHeader );
455         p_recv->pv_resume               = p_recv->pv_buf;
456         p_recv->pv_recv_before  = NULL;
457         p_recv->pv_recv_next    = NULL;
458         p_recv->i_fds_id                = i_socket;
459
460         return;
461 }
462
463
464 EXTERN_SERVER_RECVSTATUS
465 Drd64_Server_RecvStatus *
466         Drd64_Server_RecvStatus_GetRecvStatus(
467                 int             i_recv_id )
468 {
469         return *(gpp_recvstat + i_recv_id);
470 }
471
472
473 EXTERN_SERVER_RECVSTATUS
474 int
475         Drd64_Server_RecvStatus_GetSocketID(
476                 int             i_recv_id )
477 {
478         Drd64_Server_RecvStatus         *p_recv;
479         p_recv  = *(gpp_recvstat + i_recv_id);
480         
481         if( NULL == p_recv )    { return -1; }
482
483         return p_recv->i_fds_id;
484 }
485
486
487 EXTERN_SERVER_RECVSTATUS
488 int
489         Drd64_Server_RecvStatus_GetPacketStatus(
490                 int             i_recv_id )
491 {
492         Drd64_Server_RecvStatus         *p_recv;
493         p_recv  = *(gpp_recvstat + i_recv_id);
494         
495         if( NULL == p_recv )    { return -1; }
496
497         return p_recv->b_recv_status;
498 }
499
500
501 EXTERN_SERVER_RECVSTATUS
502 int
503         Drd64_Server_RecvStatus_GetCmdStatus(
504                 int             i_recv_id )
505 {
506         Drd64_Server_RecvStatus         *p_recv;
507         p_recv  = *(gpp_recvstat + i_recv_id);
508         
509         if( NULL == p_recv )    { return -1; }
510
511         return p_recv->i_command_status;
512 }
513
514
515 EXTERN_SERVER_RECVSTATUS
516 int
517         Drd64_Server_RecvStatus_SetCmdStatus(
518                 int             i_recv_id,
519                 int             i_command_status )
520 {
521         Drd64_Server_RecvStatus         *p_recv;
522         p_recv  = *(gpp_recvstat + i_recv_id);
523         
524         if( NULL == p_recv )    { return -1; }
525
526         p_recv->i_command_status        = i_command_status;
527
528         return p_recv->i_command_status;
529 }
530
531
532 EXTERN_SERVER_RECVSTATUS
533 int
534         Drd64_Server_RecvStatus_GetRecvStatMax(
535                 void )
536 {
537         return gi_recvstat_max;
538 }
539
540
541 EXTERN_SERVER_RECVSTATUS
542 Drd64_Server_RecvStatus *
543         Drd64_Server_RecvStatus_GetResumeChainStart(
544                 void )
545 {
546         return gp_recv_resume_start;
547 }
548
549
550 EXTERN_SERVER_RECVSTATUS
551 Drd64_Server_RecvStatus *
552         Drd64_Server_RecvStatus_GetSocketsChainStart(
553                 void )
554 {
555         return gp_recv_sockets_start;
556 }
557
558
559 /* EOF of drd64_.c ----------------------------------- */