home *** CD-ROM | disk | FTP | other *** search
/ Chip 2002 March / Chip_2002-03_cd2.bin / dmbsck.cab / dumb_socket.c next >
C/C++ Source or Header  |  2001-11-14  |  21KB  |  930 lines

  1. /* 
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    
  7.    This program is distributed in the hope that it will be useful,
  8.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.    GNU General Public License for more details.
  11.    
  12.    You should have received a copy of the GNU General Public License
  13.    along with this program; if not, write to the Free Software
  14.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  15.  
  16. /* dumb sockets */
  17.  
  18.  
  19. #define DUMB_SOCKET_EXPORTS
  20.  
  21.  
  22. //#define _WATCH_POMALA
  23.  
  24.  
  25. #include <windows.h>
  26. //#include <winbase.h>
  27. #include <stdlib.h>
  28. #include <memory.h>
  29. #include <assert.h>
  30. #include <stdio.h>
  31. #include "watcha.h"
  32. #include "dumb_socket.h"
  33. #include "pchfree.h"
  34.  
  35. /* muzu vypnout inline */
  36. #define INLINE __inline
  37.  
  38. /* count u semaforu */
  39. #define MAX_SEM_COUNT 10000
  40.  
  41. #ifdef _DEBUG
  42. static int pocet_spojeni = 0;
  43. static int            pipe_counter    = 0;
  44. #endif
  45.  
  46. static int            dumbs_item_empty    (dumbs_item* me);    /* je empty? */
  47. static void            delete_dumb_pipe    (dumb_pipe* p);
  48. static dumb_socket*    new_dumb_socket        ();
  49. static void         dumb_socket_push    (dumb_socket* me, void*  data, int  size);
  50. static int          dumb_socket_pop        (dumb_socket* me, void*  data, int  size);
  51. static void         dumb_socket_unpop    (dumb_socket* me, void* _data, int _size);
  52. static int          dumb_socket_empty    (dumb_socket* me);
  53. static void         delete_dumb_socket    (dumb_socket* me);
  54. static int             dumb_socket_pop_size    (dumb_socket* me);
  55. static void         dumb_socket_lock    (dumb_socket* me);
  56. static void         dumb_socket_unlock    (dumb_socket* me);
  57. static void         wait_for_data        (dumb_socket* me);
  58. static void         signal_data        (dumb_socket* me);
  59. static dumb_pipe*    remove_dumb_pipe(dumb_pipe* p);
  60. static dumb_pipe*    new_dumb_pipe(dumb_pipe* chain, short blocking, char* name);
  61. static void            delete_dumbs_item(dumbs_item* me);
  62. static dumbs_item*    new_dumbs_item(void* _data, int _size);
  63. static void            dumbs_item_append(dumbs_item* me,dumbs_item* i);
  64. static void            dumbs_item_prepend(dumbs_item* me,dumbs_item* i);
  65. static void            unlocked_item_remove(dumbs_item* me);
  66. static int            dumbs_item_get(dumbs_item* me, void* buf, int bufsize);
  67.  
  68.  
  69. static dumb_pipe*    pipe_chain        = NULL;
  70. CRITICAL_SECTION    create_pipe_lock;
  71. CRITICAL_SECTION    hdumb_lock;
  72.  
  73.  
  74. #define WBUFMAX    48
  75. #define WBUFMAXHEX    16
  76.  
  77. void wbuf( char* buf, int size)
  78. {
  79.     char wbuf[512];
  80.     char* wp = wbuf;
  81.     int i;
  82.  
  83.     if( size > WBUFMAX) size = WBUFMAX;
  84.     for( i = 0; i < size; i++) {
  85.         if( buf[i] >= ' ' && buf[i] < 128)
  86.             *wp++ = buf[i];
  87.         else
  88.             *wp++ = '.';
  89.     }
  90.  
  91.     while( i++ < WBUFMAX)
  92.         *wp++ = ' ';
  93.  
  94.     if( size > WBUFMAXHEX) size = WBUFMAXHEX;
  95.     for( i = 0; i < size; i++) {
  96.         wp += sprintf( wp, " %02X", buf[i] & 0xFF);
  97.     }
  98.  
  99.     *wp = 0;
  100.     w( wbuf);
  101. }
  102.  
  103.  
  104. //prace se semaphorama
  105. static void wait_for(HANDLE h)    // vola se jen z connectu a z wait_for_data a to zase jen z read_dumb_pipe
  106. {
  107.     DWORD res;
  108.     assert(h != NULL);
  109. #ifdef _WATCH_POMALA
  110.     watch_in( "wait for %08X ...", h);
  111. #endif
  112.     res = WaitForSingleObject(h,INFINITE);
  113. #ifdef _WATCH_POMALA
  114.     watch_out( "wait for %08X OK (%d)", h, res);
  115. #endif
  116.     assert(res == WAIT_OBJECT_0);
  117. }
  118.  
  119.  
  120. static void release(HANDLE h)
  121. {
  122.     BOOL res;
  123.     assert(h);
  124. #ifdef _WATCH_POMALA
  125.     w( "release %08X", h);
  126. #endif
  127.     res = ReleaseSemaphore(h,1,NULL);
  128.     if( ! res) {
  129.         DWORD errc = GetLastError();
  130.          w( "!!!! Release semaphor %08X FAILED - errc: %d !!!!", h, errc);
  131.     }
  132.     assert( res);
  133. }
  134.  
  135.  
  136. static void hlock( int c)
  137. {
  138.     watch_in( "hlock %c", c);
  139.     EnterCriticalSection(&hdumb_lock);
  140. }
  141.  
  142. static void hunlock( int c)
  143. {    
  144.     LeaveCriticalSection(&hdumb_lock);
  145.     watch_out( "hunlock %c", c);
  146. }
  147.  
  148.  
  149. static void clock( int c)
  150. {
  151.     watch_in( "clock %c", c);
  152.     EnterCriticalSection(&create_pipe_lock);
  153. }
  154.  
  155. static void cunlock( int c)
  156. {
  157.     LeaveCriticalSection(&create_pipe_lock);        
  158.     watch_out( "cunlock %c", c);
  159. }
  160.  
  161.  
  162. void dumb_socket_lock(dumb_socket* me)
  163. {
  164.     assert( me);
  165. //    watch_in( "Lock sock %08X", me);
  166.     EnterCriticalSection(&me->lock);
  167. #if _DEBUG
  168.     me->locked = 1;
  169. #endif
  170. }
  171.  
  172. void dumb_socket_unlock(dumb_socket* me)
  173. {
  174.     assert( me);
  175. //    watch_out( "Lock sock %08X", me);
  176. #if _DEBUG
  177.     me->locked = 0;
  178. #endif
  179.     LeaveCriticalSection(&me->lock);
  180. }
  181.  
  182.  
  183. void wait_for_data(dumb_socket* me)
  184. {
  185. //    w( "Wait for data S:%08X", me);
  186.     wait_for(me->block_sem);
  187. }
  188.  
  189. void signal_data(dumb_socket* me)
  190. {
  191. //    w( "Signal data S:%08X", me);
  192.     release(me->block_sem);
  193. }
  194.  
  195. static HANDLE create_semaphore()
  196. {
  197.     HANDLE h;
  198.     h = CreateSemaphore(NULL,0,MAX_SEM_COUNT,NULL);
  199.     w( "Sem %08X crtd", h);
  200.     assert( h);
  201.     return h;
  202. }
  203.  
  204. static void delete_semaphore(HANDLE h)
  205. {
  206.     int r;
  207.     
  208.     r = CloseHandle( h);
  209. #ifdef _DEBUG
  210.     if( ! r)
  211.         w( "!!! Sem %08X delete FAILED - error %d", h, GetLastError());
  212.     else
  213.         w( "Sem %08X deleted", h);
  214.     assert(r);
  215. #endif
  216. }
  217.  
  218. ////////////////////////////////////////////////////////////////////
  219. ////////////////////////////////////////////////////////////////////
  220. ////////////////////////////////////////////////////////////////////
  221.  
  222. HANDLE podivny_creatovac;
  223. HANDLE podivny_konektovac;
  224.  
  225.  
  226. ////////////////////////////////////////////////////////////////////
  227. // Volne funkce 
  228.  
  229. static hdumb_pipe* new_hdumb_pipe(dumb_pipe* p,short i_am_server)
  230. {
  231.  
  232.     hdumb_pipe* n = (hdumb_pipe*) malloc(sizeof(hdumb_pipe));
  233. //    watch("new_hdumb_pipe");
  234. //@F    hlock( 'n');    
  235.     
  236.     memset((void*)n,0,sizeof(hdumb_pipe));
  237.     n->pipe      = p;
  238.     n->server = i_am_server;
  239. //@F    hunlock( 'N');
  240.     return n;
  241. }
  242.  
  243.  
  244. /* vola server */
  245. int connect_hdumb_pipe(hdumb_pipe* h)
  246. {
  247.     watch_in("connect_hdumb_pipe");
  248.     //rekni_ze_cekam();
  249.     
  250.     ReleaseSemaphore(podivny_konektovac,1,NULL);
  251.     wait_for(h->pipe->connect_synchro);
  252.     
  253.     watch_out("connect_hdumb_pipe");
  254.     return 1;
  255. }
  256. /*
  257. // vola client .... uz nevola
  258. int wait_hdumb_pipe(char *name,int timeout)
  259. {
  260.     DWORD res = WaitForSingleObject(podivny_konektovac,0);
  261.     if(res == WAIT_OBJECT_0){
  262.         ReleaseSemaphore(podivny_konektovac,1,NULL);
  263.         return 1;
  264.     }
  265.     return 0;
  266. }
  267. */
  268.  
  269.  
  270. ////////////////////////////////////////////////////////////////////
  271. // Funkce pristupujici ke globalnim promennym (pipechain), tudiz v nich musi bejt lock
  272. // hlock
  273.  
  274. void destroy_dumb_pipe(hdumb_pipe* h)
  275. {
  276.     hlock( 'd');
  277.     
  278.     assert( h);
  279.     assert( h->pipe);
  280.     watch_in( "destroy_dumb_pipe h:%08X %c p:%08X s:[%08X,%08X]", h, h->server ? 'S' : 'C', 
  281.         h->pipe, h->pipe->dumb_sock[0], h->pipe->dumb_sock[1]);
  282.  
  283. //    EnterCriticalSection(&create_pipe_lock);
  284.     if(h && h->pipe) {
  285.         remove_dumb_pipe( h->pipe);
  286.         delete_dumb_pipe( h->pipe);
  287.         pchfree(h);
  288.     }
  289. //    LeaveCriticalSection(&create_pipe_lock);
  290.     watch_out("destroy_dumb_pipe");
  291.     hunlock( 'D');
  292. }
  293.  
  294.  
  295. ////////////////////////////////////////////////////////////////////
  296. // Funkce pristupujici ke globalnim promennym (pipechain), tudiz v nich musi bejt lock
  297. // clock
  298.  
  299. hdumb_pipe* create_server_dumbpipe(short blocking, char *name)
  300. {
  301.     hdumb_pipe* h;
  302.  
  303.     clock( 's');
  304.     
  305.     pipe_chain = new_dumb_pipe(pipe_chain,blocking,name);
  306.     h = new_hdumb_pipe(pipe_chain,I_AM_SERVER);
  307.     assert( h);
  308.     assert(++pocet_spojeni<2);
  309.     w( "create S dumbpipe [%s] H:%08X P:%08X S:[%08X,%08X]", name, h, h->pipe, 
  310.         h->pipe ? h->pipe->dumb_sock[0] : 0, h->pipe ? h->pipe->dumb_sock[1] : 0);
  311.     //ReleaseSemaphore(podivny_creatovac,1,NULL);
  312.     cunlock( 'S');
  313.     return h;
  314. }
  315.  
  316.  
  317. hdumb_pipe* create_client_dumbpipe(char *name)
  318. {
  319.     dumb_pipe* pom;
  320.     hdumb_pipe* h;
  321.     DWORD res;
  322.  
  323.     //WaitForSingleObject(podivny_creatovac,INFINITE);
  324.     res = WaitForSingleObject(podivny_konektovac,INFINITE);
  325.     if(res == WAIT_TIMEOUT){
  326.         SetLastError(ERROR_PIPE_BUSY);
  327.         return INVALID_HANDLE_VALUE;
  328.     }
  329.     clock( 'c');
  330.     
  331.     watch_in("create_client_dumbpipe");
  332.  
  333.     pom = pipe_chain;
  334.     while(pom != NULL){
  335.         //watch("step");
  336. #ifndef NONAME_PIPE
  337.         assert(pom->name != NULL);
  338.         if(pom->name != NULL){
  339.             if(0==strcmp(pom->name,name)){
  340. #endif
  341.                 assert(--pocet_spojeni >= 0);
  342.                 assert(pom->connected != 1);
  343.                 pom->connected=1;
  344.                 h = new_hdumb_pipe(pom,I_AM_CLIENT);
  345.                 w("create C dumbpipe [%s] H:%08X P:%08X S:[%08X,%08X]", name, h, h->pipe, 
  346.                     h->pipe ? h->pipe->dumb_sock[0] : 0, h->pipe ? h->pipe->dumb_sock[1] : 0);
  347.                 
  348.                 release(h->pipe->connect_synchro);
  349.                 watch_out("create_client_pipe OK");
  350.                 cunlock( 'C');
  351.                 return h;
  352. #ifndef NONAME_PIPE
  353.             }
  354.         }
  355. #endif
  356.         pom = pom->next;
  357.     }
  358.     watch_out("create_client_pipe ERR");
  359.     cunlock( 'C');
  360.     assert(0);
  361.     SetLastError(ERROR_BAD_PIPE);
  362.     return INVALID_HANDLE_VALUE;
  363. }
  364.  
  365.  
  366.  
  367.  
  368. ////////////////////////////////////////////////////////////////////
  369. // Funkce, ktery jsou uz volany z hlock
  370.  
  371.  
  372. static dumb_pipe* remove_dumb_pipe(dumb_pipe* p)
  373. {
  374.     dumb_pipe* c = pipe_chain;
  375.     dumb_pipe* last = NULL; //@petr dame nejakou rozumnou hodnotu
  376.     
  377.     while(c != NULL){
  378.         if(c == p){
  379.             if(c==pipe_chain){
  380.                 pipe_chain=pipe_chain->next;
  381.                 return c;
  382.             }else{
  383.                 assert(last != NULL); 
  384.                 last->next = c->next;
  385.                 return c;
  386.             }
  387.         }
  388.         last = c;
  389.         c = c->next;
  390.     }
  391.     return NULL;
  392. }
  393.  
  394.  
  395. ////////////////////////////////////////////////////////////////////
  396. // Funkce, ktery jsou uz volany z clock
  397.  
  398.  
  399. static dumb_pipe* new_dumb_pipe(dumb_pipe* chain, short blocking, char* name)
  400. {
  401.     dumb_pipe* n = (dumb_pipe*) malloc(sizeof(dumb_pipe));
  402. //    int len;
  403.     memset((void*)n,0,sizeof(dumb_pipe));
  404. #ifndef NONAME_PIPE
  405.     len = strlen(name);
  406.     n->name = malloc(len * sizeof(char)+1);
  407.     strcpy(n->name,name);
  408. #endif
  409.     n->next = chain;
  410.     n->dumb_sock[0] = new_dumb_socket(blocking);
  411.     n->dumb_sock[1] = new_dumb_socket(blocking);
  412.     n->blocking = blocking;
  413.     n->connected = 0;
  414.     n->connect_synchro = create_semaphore();
  415.     chain = n;
  416.     
  417.     return n;
  418. }
  419.  
  420.  
  421. ////////////////////////////////////////////////////////////////////
  422. // Funkce pristupujici k retizku uvnitr socketu, musi byt lock(sock)
  423.  
  424. int write_dumb_pipe(hdumb_pipe* h,char* buff,int size)
  425. {
  426.     dumb_socket* sock;
  427. //@F    hlock( 'w');        - to tu podle mne nema bejt
  428.  
  429.     assert( h);
  430.     assert( h->pipe);
  431.     assert( h->pipe->dumb_sock[h->server]);
  432.     assert( buff);
  433.  
  434.     /*if(!h->pipe->full){
  435.         wait_for(h->pipe->connect_synchro);
  436.     }*/
  437. //    assert(h->pipe->full);
  438.     sock = h->pipe->dumb_sock[h->server];
  439.     
  440.     dumb_socket_lock( sock);
  441.     dumb_socket_push( sock, buff, size);
  442.     signal_data( sock);
  443.     dumb_socket_unlock( sock);
  444.     w( "W  H:%08X %c P:%08X S:%08X size %d", h, h->server ? 'S' : 'C', h->pipe, sock, size);
  445.     //wbuf( buff, size);
  446. //@F    hunlock( 'W');        
  447.     return size;
  448. }
  449.  
  450. int read_dumb_pipe(hdumb_pipe* h,char* buff,int buf_size)
  451. {
  452.     int pop_size;
  453.     dumb_socket* sock;
  454.     char* tmpbuf;
  455.     
  456.     assert(h    != NULL);
  457.     assert(h->pipe  != NULL);
  458.     assert(h->pipe->dumb_sock[!h->server] != NULL);
  459.     assert(buff    != NULL);
  460.     assert(buf_size);
  461.  
  462.     sock = h->pipe->dumb_sock[!h->server];
  463.  
  464.     assert( ! sock->next_zombie);
  465.  
  466. #ifdef WITH_TIMEOUT
  467.     if(!wait_for_data(sock)){
  468.         return 0; 
  469.     }
  470. #else
  471.     wait_for_data(sock);
  472. #endif
  473. //@F    hlock( 'r');    
  474.     
  475.     dumb_socket_lock(sock);
  476.     //watch("lock");
  477.     pop_size = dumb_socket_pop_size(sock);
  478.     if(pop_size <= buf_size){
  479.  
  480.     //    watch("pop");
  481.         dumb_socket_pop(sock,buff,buf_size);
  482.         dumb_socket_unlock(sock);
  483. //@     hunlock( 'P');    - to tu podle mne nema bejt
  484.  
  485.         w( "RP h:%08X %c p:%08X s:%08X size %d", h, h->server ? 's' : 'c', h->pipe, sock, buf_size);
  486.         //wbuf( buff, buf_size);
  487.  
  488.         return pop_size;
  489.     }else{
  490.     //    watch("unpop");
  491.         tmpbuf = malloc(pop_size);
  492.         dumb_socket_pop(sock,tmpbuf,pop_size);
  493.  
  494.         if(buf_size) {
  495.             memcpy(buff,tmpbuf,buf_size);
  496.         }
  497.  
  498. #ifdef _WATCH_POMALA
  499.         w( "RU h:%08X %c p:%08X s:%08X size %d", h, h->server ? 's' : 'c', h->pipe, sock, buf_size);
  500.         //wbuf( buff, buf_size);
  501. #endif
  502.  
  503.         dumb_socket_unpop(sock,tmpbuf+buf_size,pop_size-buf_size);
  504.         signal_data(sock);
  505.         pchfree(tmpbuf);
  506.         dumb_socket_unlock(sock);
  507.     //    watch_out("read_dumb_pipe (unpop)");
  508. //@F        hunlock( 'U');        
  509.     //    watch("unlock");
  510.         return buf_size;
  511.     }
  512. }
  513.  
  514. //@F
  515. void make_empty_dumb_socket( dumb_socket* me)
  516. {
  517.     dumb_socket_lock(me);
  518.     // DeleteCriticalSection(&me->lock); - az v totally kill
  519.     // puvodne: se vola az s detache dllka, kdyz se dezombizuje ;)
  520.     //delete_semaphore(me->block_sem);
  521.  
  522.     while( ! dumb_socket_empty( me)) {
  523.         dumbs_item* tmp = me->first;
  524.         if(me->last == me->first) {
  525.             me->last = NULL;
  526.         }
  527.         me->first = me->first->next;
  528.         delete_dumbs_item(tmp);
  529.     }
  530.     dumb_socket_unlock(me);
  531. }
  532.  
  533. ////////////////////////////////////////////////////////////////////
  534. // Funkce pristupujici k retizku uvnitr zalockovaneho socketu
  535.  
  536.  
  537. void dumb_socket_push(dumb_socket* me,void* data,int size)
  538. {
  539.     dumbs_item* i;
  540. //    char buff[500];
  541.  
  542.     assert( me);
  543.     assert( data);
  544.     assert( size > 0);
  545.  
  546. //    sprintf(buff,"dumb_socket_push #%s#(%d)",data,size);
  547. //    watch(buff);
  548.     i = new_dumbs_item( data, size);
  549.     assert( i);
  550.  
  551.     if(dumb_socket_empty(me)){
  552.         me->first    = i;
  553.         me->last    = i;
  554.     }else{
  555.         dumbs_item_append(i,me->last);
  556.         me->last=i;
  557.     }
  558. }
  559.  
  560.  
  561. void dumb_socket_unpop(dumb_socket* me, void* _data, int _size)
  562. {
  563.     dumbs_item* i;
  564.  
  565.     assert( me);
  566.     assert( _data);
  567.  
  568.     i = new_dumbs_item(_data,_size);
  569.     assert( i);
  570.  
  571.     if(dumb_socket_empty(me)){
  572.         me->first    = i;
  573.         me->last    = i;
  574.     }else{
  575.         dumbs_item_prepend(i,me->first);
  576.         me->first    = i;
  577.     }
  578. }
  579.  
  580. int dumb_socket_pop(dumb_socket* me, void* _data, int _size)
  581. {
  582.     dumbs_item* tmp;
  583.     int read;
  584.  
  585.     assert( me);
  586.     assert( _data);
  587.  
  588.     if( ! dumb_socket_empty( me)){
  589.         read = dumbs_item_get( me->first, _data, _size);
  590. //        w("%d = dumb_socket_pop (%s,%d)",read,_data,_size);
  591.         tmp = me->first;
  592.         if(me->last == me->first){
  593.             me->last = NULL;
  594.         }
  595.         me->first = me->first->next;
  596. //        dumbs_item_remove(tmp);
  597.         delete_dumbs_item(tmp);
  598.         return read;
  599.     }
  600.     return 0;
  601. }
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608. ////////////////////////////////////////////////////////////////////
  609. ////////////////////////////////////////////////////////////////////
  610. ////////////////////////////////////////////////////////////////////
  611.  
  612.  
  613.  
  614.  
  615.  
  616. static void delete_dumb_pipe(dumb_pipe* p)
  617. {
  618.     int i;
  619.     clock( 'd');
  620.     assert( p);
  621.     assert( p->dumb_sock[0]);
  622.     assert( p->dumb_sock[1]);
  623.     w( "delete_dumb_pipe p:%08X s:[%08X,%08X]", p, p->dumb_sock[0], p->dumb_sock[1]);
  624. //    release(p->exclusive_synchro);
  625. //EnterCriticalSection(&create_pipe_lock);
  626.     if(p != NULL)
  627.         for(i = 0; i <=1; i++)
  628.             if(p->dumb_sock[i] != NULL)
  629.                 delete_dumb_socket(p->dumb_sock[i]);
  630.     delete_semaphore(p->connect_synchro);    
  631.     pchfree(p);
  632.     cunlock( 'D');
  633. }
  634.  
  635.  
  636.  
  637.  
  638.  
  639. //////////////////////////////////////////////////////////////////////////////
  640. //////////////////////////////////////////////////////////////////////////////
  641. //////////////////////////////////////////////////////////////////////////////
  642.  
  643.  
  644. void dumbs_item_free(dumbs_item* me)
  645. {
  646.     assert(!dumbs_item_empty(me));
  647.     if(!dumbs_item_empty(me)){
  648.         pchfree(me->data);
  649.         me->data = NULL;
  650.         me->size = 0;
  651.     }
  652.     //watch_out("dumb_item_free");
  653. }
  654.  
  655.  
  656.  
  657. static void dumbs_item_set(dumbs_item* me, void* _data, int _size)
  658. {
  659.     if(!dumbs_item_empty(me)){
  660.         dumbs_item_free(me);
  661.     }
  662.  
  663.     me->size = _size;
  664.     if(_size)
  665.         me->data = malloc(_size);
  666.     else
  667.         me->data = NULL;
  668.     assert(me->data != NULL);
  669.     if(me->data != NULL)
  670.     {
  671.         // w( "dumbs_item_set(%08X,%08X) MEMCPY(%08X,%08X,%d)", me, me->data, me->data, _data, _size);
  672.         memcpy (me->data,_data,_size);
  673.     }
  674. }
  675.  
  676. static int dumbs_item_get(dumbs_item* me, void* buf, int bufsize)
  677. {
  678.     int r;
  679.  
  680.     assert(me != NULL);
  681.     assert(buf != NULL);
  682.  
  683.     if(me == NULL || buf == NULL)
  684.         return 0;
  685.     
  686.     if(bufsize < me->size){
  687.         r = bufsize;
  688.     }else{
  689.         r = me->size;
  690.     }
  691.     if(r){
  692.         //w("dumbs_item_get %08x,size=%d",buf,r);
  693.         memcpy(buf,me->data, r);
  694.     }
  695.     return r;
  696. }
  697.  
  698. static dumbs_item* new_dumbs_item(void* _data, int _size)
  699. {
  700.  
  701.     dumbs_item* n = (dumbs_item*) malloc(sizeof(dumbs_item));
  702.     assert(n != NULL);
  703.     
  704.     n->prev = NULL;
  705.     n->next = NULL;
  706.     n->data = NULL;
  707.     n->size = 0;
  708. #if _DEBUG
  709.     n->locked = 0;
  710. #endif
  711.  
  712.     InitializeCriticalSection(&n->lock);
  713.     
  714.     assert( _data);
  715.     dumbs_item_set(n, _data, _size);
  716.  
  717.     return n;
  718. }
  719.  
  720. static void dumbs_item_append(dumbs_item* me,dumbs_item* i)
  721. {
  722.     assert(me != NULL);
  723.     assert(i != NULL);
  724.     if(i != NULL) {
  725.         if( i->next)
  726.             w( "!!!! i->next not empty - i: %08X, i->next: %08X", i, i->next);
  727.         assert( ! i->next);
  728.         i->next = me;
  729.     }
  730.     me->prev = i;
  731. }
  732.  
  733. static void dumbs_item_prepend(dumbs_item* me,dumbs_item* i)
  734. {
  735.     assert( me);
  736.     assert( i);
  737.     if( i) {
  738.         if( i->prev)
  739.             w( "!!!! i->prev not empty - i: %08X, i->prev: %08X", i, i->prev);
  740.         assert( ! i->prev);
  741.         i->prev = me;
  742.     }
  743.     me->next = i;
  744. }
  745.  
  746. /* remove z locknuty struktury */
  747. static void unlocked_item_remove(dumbs_item* me)
  748. {
  749.     if(me->prev != NULL)
  750.         me->prev->next = me->next;
  751.     if(me->next != NULL)
  752.         me->next->prev = me->prev;
  753.     me->prev = NULL;
  754.     me->next = NULL;
  755. }
  756.  
  757. INLINE void dumbs_item_remove(dumbs_item* me)
  758. {
  759.     assert(me != NULL);
  760.     unlocked_item_remove(me);
  761. }
  762.  
  763. INLINE int dumbs_item_size(dumbs_item* me)
  764. {
  765.     int s;
  766.     assert(me != NULL);
  767.     s = me->size;
  768.     return s;
  769. }
  770.  
  771. INLINE int dumbs_item_empty(dumbs_item* me)
  772. {
  773.     int r = 0;
  774.     assert(me != NULL);
  775.     if(me != NULL){
  776.         if(me->data == NULL)
  777.             r = 1;
  778.         else
  779.             r = 0;
  780.     }
  781.     return r;
  782. }
  783.  
  784.  
  785. static void delete_dumbs_item(dumbs_item* me)
  786. {
  787. #if _DEBUG
  788. //    w( "delete_dumbs_item(%08X)", me);
  789. #endif
  790.     assert(me != NULL);
  791.     if(me != NULL){
  792.         unlocked_item_remove(me);
  793.         if(!me->size == 0){
  794.             dumbs_item_free(me);
  795.         }
  796.         pchfree(me);
  797.     }
  798. }
  799.  
  800. //////////////////////////////////////////////
  801.  
  802. static dumb_socket* dumb_socket_zombie = NULL;
  803.  
  804.  
  805. INLINE int dumb_socket_pop_size(dumb_socket* me)
  806. {
  807.     return me->first ? me->first->size : 0;
  808. }
  809.  
  810. INLINE int dumb_socket_empty(dumb_socket* me)
  811. {
  812.     return ! me->first;
  813. }
  814.  
  815.  
  816. dumb_socket* new_dumb_socket(short blocking)
  817. {
  818.     //char kbuf[256];
  819.     dumb_socket* n = malloc(sizeof(dumb_socket));
  820.     assert(n != NULL);
  821.     if(n != NULL){
  822.         n->first = NULL;
  823.         n->last = NULL;
  824.         n->blocking = blocking;
  825.         n->block_sem = create_semaphore();
  826.  
  827.         InitializeCriticalSection(&n->lock);
  828. #if _DEBUG
  829.         n->locked = 0;
  830. #endif
  831.         n->next_zombie = NULL;
  832.     }
  833.  
  834.     /*sprintf(kbuf, "new_dumb_socket(%08X)", n);
  835.     watch(kbuf);*/
  836.     return n;
  837. }
  838.  
  839.  
  840.  
  841. //@F
  842. void totally_kill_dumb_socket( dumb_socket* me)
  843. {
  844. /* tohle uz se nevola, ted uz se o to nema kdo hadat
  845.     dumb_socket_lock(me);
  846.     dumb_socket_unlock(me);
  847. */
  848.     w( "totally_kill_dumb_socket S:%08X", me);
  849.     make_empty_dumb_socket( me);    // pro sichr
  850.     DeleteCriticalSection(&me->lock);
  851.     delete_semaphore(me->block_sem);
  852.     // me->block_sem = INVALID_HANDLE_VALUE; to uz tu taky nema co delat
  853.     pchfree(me);
  854. }
  855.  
  856.  
  857. //@F
  858. #define NO_ZOMBIE_CHAIN
  859. #ifdef NO_ZOMBIE_CHAIN
  860. static dumb_socket* zombie_next = 0;
  861. #endif
  862.  
  863. void delete_dumb_socket(dumb_socket* me)
  864. {
  865.     w( "delete_dumb_socket S:%08X", me);
  866.     assert(me != NULL);
  867.     make_empty_dumb_socket( me);    // pozor, lock musi byt az za tim, tady vevnitr lock je
  868.     dumb_socket_lock(me);
  869.  
  870. #ifdef NO_ZOMBIE_CHAIN
  871.     // jedna pipa ma dva sockety, pamatuje si to vzdycky posledni dvojici, protoze to je serializovany
  872.     // jakmile pride delete, tak se smazou ty predchozi
  873.     if( dumb_socket_zombie) {
  874.         if( zombie_next) {
  875.             totally_kill_dumb_socket( dumb_socket_zombie);
  876.             dumb_socket_zombie = zombie_next;
  877.         }
  878.         zombie_next = me;
  879.     } else {
  880.         dumb_socket_zombie = me;
  881.     }
  882. #else
  883.     me->next_zombie = dumb_socket_zombie;
  884.     dumb_socket_zombie = me;
  885. #endif
  886.     //!!! DeleteCriticalSection(&me->lock); se vola az s detache dllka, kdyz se dezombizuje ;)
  887.     //delete_semaphore(me->block_sem);
  888.     dumb_socket_unlock(me);
  889. }
  890.  
  891.  
  892. HANDLE hinstance;
  893.  
  894. BOOL APIENTRY DllMain( HANDLE hModule, DWORD  ul_reason_for_call, LPVOID lpReserved)
  895. {
  896.     int n = 0;
  897.  
  898.     switch (ul_reason_for_call)
  899.     {
  900.         case DLL_PROCESS_ATTACH:
  901.             hinstance = hModule;
  902.             InitializeCriticalSection(&create_pipe_lock);
  903.             InitializeCriticalSection(&hdumb_lock);
  904.             podivny_konektovac = CreateSemaphore(NULL,0,1,NULL);
  905.             podivny_creatovac = CreateSemaphore(NULL,0,1,NULL);
  906.             break;
  907.         case DLL_THREAD_ATTACH:
  908.         case DLL_THREAD_DETACH:
  909.             break;
  910.         case DLL_PROCESS_DETACH:
  911.             while( dumb_socket_zombie){
  912.                 dumb_socket* me = dumb_socket_zombie;
  913.                 dumb_socket_zombie = me->next_zombie;
  914.                 n++;
  915.                 totally_kill_dumb_socket( me);
  916.             }
  917. #ifdef NO_ZOMBIE_CHAIN
  918.             if( zombie_next) {
  919.                 totally_kill_dumb_socket( zombie_next);
  920.                 n++;
  921.             }
  922. #endif
  923.             DeleteCriticalSection(&create_pipe_lock);
  924.             DeleteCriticalSection(&hdumb_lock);
  925.             w( "zombie sockets: %d", n);
  926.             break;
  927.     }
  928.     return TRUE;
  929. }
  930.