OSDN Git Service

(LibGoblin)
[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         }
332
333         i_recv_id       = i_cnt;
334         p_recv_self->i_recvstatus_id    = i_cnt;
335         *(gpp_recvstat + p_recv_self->i_recvstatus_id)  = p_recv_self;
336         if( gi_recv_resume_max == i_cnt )       {
337                 gi_recv_resume_max++;
338         }
339         
340         return i_recv_id;
341 }
342
343
344 EXTERN_SERVER_RECVSTATUS
345 int
346         Drd64_Server_RecvStatus_DeleteResumeChain(
347                 int             i_recv_id )
348 {
349         Drd64_Server_RecvStatus *p_recv_self;
350         Drd64_Server_RecvStatus *p_recv_before;
351         Drd64_Server_RecvStatus *p_recv_next;
352
353
354         p_recv_self     = *(gpp_recvstat + i_recv_id);
355         if( NULL == p_recv_self )       {
356                 return 0x01;
357         }       
358
359         p_recv_before   = (Drd64_Server_RecvStatus *)p_recv_self->pv_recv_before;
360         p_recv_next             = (Drd64_Server_RecvStatus *)p_recv_self->pv_recv_next;
361
362         if( NULL != p_recv_before )     {
363                 p_recv_before->pv_recv_next     = (void *)p_recv_next;
364         }
365
366         if( NULL != p_recv_next )       {
367                 p_recv_next->pv_recv_before     = (void *)p_recv_before;
368         }
369
370         if( gp_recv_resume_end == p_recv_self )         {
371                 gp_recv_resume_end              = p_recv_before;
372         }
373
374         if( p_recv_self->i_recvstatus_id == (gi_recv_resume_max - 1) )  {
375                 gi_recv_resume_max--;
376         }
377
378         if( FD_SETSIZE == gi_recv_resume_max )  {
379                 gp_recv_resume_start    = NULL;
380                 gp_recv_resume_end              = NULL;
381         }
382
383         *(gpp_recvstat + i_recv_id)             = NULL;
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_command_status        = DRD64_SERVER_CMDSTATUS_STATUS_NORMAL;
455         p_recv->i_remain_bytes          = sizeof( Drd64_PacketHeader );
456         p_recv->pv_resume                       = p_recv->pv_buf;
457         p_recv->pv_recv_before          = NULL;
458         p_recv->pv_recv_next            = NULL;
459         p_recv->pv_cinfo_connection     = NULL;
460         p_recv->i_fds_id                        = i_socket;
461
462         return;
463 }
464
465
466 EXTERN_SERVER_RECVSTATUS
467 int
468         Drd64_Server_RecvStatus_SetConnectionInfoPointer(
469                 Drd64_Server_RecvStatus *p_recv_now,
470                 void *pv_cinfo )
471 {
472         int             i_socket;
473         Drd64_Server_RecvStatus *p_recv_socket;
474
475         assert( NULL != p_recv_now );
476
477         p_recv_now->pv_cinfo_connection         = pv_cinfo;
478
479         p_recv_socket   = *(gpp_recvstat + p_recv_now->i_fds_id);
480         if(( NULL != p_recv_socket ) && ( p_recv_socket != p_recv_now ))        {
481                 assert( NULL == p_recv_socket->pv_cinfo_connection );
482                 p_recv_socket->pv_cinfo_connection      = pv_cinfo;
483         }
484         
485         return 0x00;
486 }
487
488
489 EXTERN_SERVER_RECVSTATUS
490 Drd64_Server_RecvStatus *
491         Drd64_Server_RecvStatus_GetRecvStatus(
492                 int             i_recv_id )
493 {
494         return *(gpp_recvstat + i_recv_id);
495 }
496
497
498 EXTERN_SERVER_RECVSTATUS
499 int
500         Drd64_Server_RecvStatus_GetSocketID(
501                 int             i_recv_id )
502 {
503         Drd64_Server_RecvStatus         *p_recv;
504         p_recv  = *(gpp_recvstat + i_recv_id);
505         
506         if( NULL == p_recv )    { return -1; }
507
508         return p_recv->i_fds_id;
509 }
510
511
512 EXTERN_SERVER_RECVSTATUS
513 int
514         Drd64_Server_RecvStatus_GetPacketStatus(
515                 int             i_recv_id )
516 {
517         Drd64_Server_RecvStatus         *p_recv;
518         p_recv  = *(gpp_recvstat + i_recv_id);
519         
520         if( NULL == p_recv )    { return -1; }
521
522         return p_recv->b_recv_status;
523 }
524
525
526 EXTERN_SERVER_RECVSTATUS
527 int
528         Drd64_Server_RecvStatus_GetCmdStatus(
529                 int             i_recv_id )
530 {
531         Drd64_Server_RecvStatus         *p_recv;
532         p_recv  = *(gpp_recvstat + i_recv_id);
533         
534         if( NULL == p_recv )    { return -1; }
535
536         return p_recv->i_command_status;
537 }
538
539
540 EXTERN_SERVER_RECVSTATUS
541 int
542         Drd64_Server_RecvStatus_SetCmdStatus(
543                 int             i_recv_id,
544                 int             i_command_status )
545 {
546         Drd64_Server_RecvStatus         *p_recv;
547         p_recv  = *(gpp_recvstat + i_recv_id);
548         
549         if( NULL == p_recv )    { return -1; }
550
551         p_recv->i_command_status        = i_command_status;
552
553         return p_recv->i_command_status;
554 }
555
556
557 EXTERN_SERVER_RECVSTATUS
558 int
559         Drd64_Server_RecvStatus_GetRecvStatMax(
560                 void )
561 {
562         return gi_recvstat_max;
563 }
564
565
566 EXTERN_SERVER_RECVSTATUS
567 Drd64_Server_RecvStatus *
568         Drd64_Server_RecvStatus_GetResumeChainStart(
569                 void )
570 {
571         return gp_recv_resume_start;
572 }
573
574
575 EXTERN_SERVER_RECVSTATUS
576 Drd64_Server_RecvStatus *
577         Drd64_Server_RecvStatus_GetSocketsChainStart(
578                 void )
579 {
580         return gp_recv_sockets_start;
581 }
582
583
584 /* EOF of drd64_.c ----------------------------------- */