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         }
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         printf( "SetPnt: %d > %d\n", p_recv_now->i_recvstatus_id, p_recv_now->i_fds_id );
477
478         p_recv_now->pv_cinfo_connection         = pv_cinfo;
479
480         p_recv_socket   = *(gpp_recvstat + p_recv_now->i_fds_id);
481         if( NULL != p_recv_socket )             {
482                 assert( NULL == p_recv_socket->pv_cinfo_connection );
483                 p_recv_socket->pv_cinfo_connection      = pv_cinfo;
484         }
485         
486         return 0x00;
487 }
488
489
490 EXTERN_SERVER_RECVSTATUS
491 Drd64_Server_RecvStatus *
492         Drd64_Server_RecvStatus_GetRecvStatus(
493                 int             i_recv_id )
494 {
495         return *(gpp_recvstat + i_recv_id);
496 }
497
498
499 EXTERN_SERVER_RECVSTATUS
500 int
501         Drd64_Server_RecvStatus_GetSocketID(
502                 int             i_recv_id )
503 {
504         Drd64_Server_RecvStatus         *p_recv;
505         p_recv  = *(gpp_recvstat + i_recv_id);
506         
507         if( NULL == p_recv )    { return -1; }
508
509         return p_recv->i_fds_id;
510 }
511
512
513 EXTERN_SERVER_RECVSTATUS
514 int
515         Drd64_Server_RecvStatus_GetPacketStatus(
516                 int             i_recv_id )
517 {
518         Drd64_Server_RecvStatus         *p_recv;
519         p_recv  = *(gpp_recvstat + i_recv_id);
520         
521         if( NULL == p_recv )    { return -1; }
522
523         return p_recv->b_recv_status;
524 }
525
526
527 EXTERN_SERVER_RECVSTATUS
528 int
529         Drd64_Server_RecvStatus_GetCmdStatus(
530                 int             i_recv_id )
531 {
532         Drd64_Server_RecvStatus         *p_recv;
533         p_recv  = *(gpp_recvstat + i_recv_id);
534         
535         if( NULL == p_recv )    { return -1; }
536
537         return p_recv->i_command_status;
538 }
539
540
541 EXTERN_SERVER_RECVSTATUS
542 int
543         Drd64_Server_RecvStatus_SetCmdStatus(
544                 int             i_recv_id,
545                 int             i_command_status )
546 {
547         Drd64_Server_RecvStatus         *p_recv;
548         p_recv  = *(gpp_recvstat + i_recv_id);
549         
550         if( NULL == p_recv )    { return -1; }
551
552         p_recv->i_command_status        = i_command_status;
553
554         return p_recv->i_command_status;
555 }
556
557
558 EXTERN_SERVER_RECVSTATUS
559 int
560         Drd64_Server_RecvStatus_GetRecvStatMax(
561                 void )
562 {
563         return gi_recvstat_max;
564 }
565
566
567 EXTERN_SERVER_RECVSTATUS
568 Drd64_Server_RecvStatus *
569         Drd64_Server_RecvStatus_GetResumeChainStart(
570                 void )
571 {
572         return gp_recv_resume_start;
573 }
574
575
576 EXTERN_SERVER_RECVSTATUS
577 Drd64_Server_RecvStatus *
578         Drd64_Server_RecvStatus_GetSocketsChainStart(
579                 void )
580 {
581         return gp_recv_sockets_start;
582 }
583
584
585 /* EOF of drd64_.c ----------------------------------- */