/[webpac]/branches/humanistika/openisis/lses.c
This is repository of my old source code which isn't updated any more. Go to git.rot13.org for current projects!
ViewVC logotype

Annotation of /branches/humanistika/openisis/lses.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 239 - (hide annotations)
Mon Mar 8 17:49:13 2004 UTC (19 years, 11 months ago) by dpavlin
Original Path: trunk/openisis/lses.c
File MIME type: text/plain
File size: 8056 byte(s)
including openisis 0.9.0 into webpac tree

1 dpavlin 237 /*
2     openisis - an open implementation of the CDS/ISIS database
3     Version 0.8.x (patchlevel see file Version)
4     Copyright (C) 2001-2003 by Erik Grziwotz, erik@openisis.org
5    
6     This library is free software; you can redistribute it and/or
7     modify it under the terms of the GNU Lesser General Public
8     License as published by the Free Software Foundation; either
9     version 2.1 of the License, or (at your option) any later version.
10    
11     This library is distributed in the hope that it will be useful,
12     but WITHOUT ANY WARRANTY; without even the implied warranty of
13     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14     Lesser General Public License for more details.
15    
16     You should have received a copy of the GNU Lesser General Public
17     License along with this library; if not, write to the Free Software
18     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19    
20     see README for more information
21     EOH */
22    
23     /*
24     $Id: lses.c,v 1.18 2003/05/26 10:55:10 kripke Exp $
25     implementation of general db access functions.
26     */
27    
28     #include <stdlib.h>
29     #include <string.h> /* memset */
30    
31     #ifdef _REENTRANT
32     #ifdef WIN32
33     # define WIN32_LEAN_AND_MEAN
34     # define NONAMELESSUNION
35     # include <windows.h>
36     /* they call it "thread local storage" */
37     # define pthread_key_t int
38     # define pthread_key_create( pkey, func ) *(pkey) = TlsAlloc()
39     # define pthread_setspecific( key, val ) TlsSetValue( key, val )
40     # define pthread_getspecific( key ) TlsGetValue( key )
41     #else
42     # include <pthread.h>
43     #endif
44     #endif
45    
46     #include "lses.h"
47    
48    
49     /* ************************************************************
50     private types
51     */
52     typedef struct {
53     Ses h;
54     /* int brk; */
55     } SesI;
56    
57     enum {
58     LSES_MAX = 0x1000,
59     LSES_MSK = 0x0fff
60     };
61    
62     /* ************************************************************
63     package data
64     */
65    
66     /* ************************************************************
67     private data
68     */
69     static Ios stdio[3] = {
70     LIO_STDINITIALIZER( "&0", LIO_IN ),
71     LIO_STDINITIALIZER( "&1", LIO_OUT|1 ),
72     LIO_STDINITIALIZER( "&2", LIO_OUT|2 )
73     };
74     static SesI cses = { /* the default session */
75     {
76     0,
77     "",
78     { stdio, stdio+1, stdio+2 },
79     -1,
80     0, 0, /* nxt, accnt */
81     {0},{0},{0}, /* times */
82     0,0,0,0 /* state */
83     }
84     };
85    
86     static SesI *tab[ LSES_MAX ] = {
87     &cses
88     };
89     static Ses *htab[ LSES_MAX ];
90     static int maxid;
91     static const char oops[] = "out of memory\n";
92    
93     #ifndef _REENTRANT
94     Session ses = &cses.h;
95     #else
96     int openisis_threaded = 42;
97     static pthread_key_t seskey;
98     #endif
99    
100     /* ************************************************************
101     private functions
102     */
103    
104     static void *memordie ( int size )
105     {
106     void *p = malloc( size );
107     if ( p )
108     return p;
109     /* TODO: ask btree to release some cache */
110     lio_write( &lio_err, oops, sizeof(oops)-1 );
111     exit( 71/*EX_OSERR*/ ); /* exit handlers MUST NOT alloc memory */
112     return 0;
113     }
114    
115    
116     /* ************************************************************
117     package functions
118     */
119    
120     void lses_init () /* called from openIsisInit */
121     {
122     #ifdef _REENTRANT
123     pthread_key_create( &seskey, 0 ); /* TODO: use ses destr func */
124     pthread_setspecific( seskey, &cses.h );
125     #endif
126     } /* lses_init */
127    
128    
129     void lses_fini () /* called from openIsisFini */
130     {
131     int i, s = LSES_MAX;
132     /* lio_write( &lio_out, "fini time\n", 9 ); */
133     while ( s-- )
134     if ( tab[s] )
135     for ( i=0; i<3; i++ )
136     if ( tab[s]->h.io[i] )
137     LIO_CLOSE( tab[s]->h.io[i] );
138     } /* lses_fini */
139    
140    
141     int lses_open ( Session s, const char *name, int flags, SFunc *type )
142     {
143     int fd = 0;
144     const char *p = name;
145     lio_sfunc *func = type ? (lio_sfunc*)type : lio_stdio;
146    
147     /* check for i<> */
148     while ( '0' <= *p && *p <= '9' )
149     fd = 10*fd + *p++ - '0';
150     if ( '<' != *p && '>' != *p )
151     p = name; /* forget it */
152     else {
153     if ( name == p && '>' == *p ) /* no fd given, > defaults to 1 */
154     fd = 1;
155     flags |= '<' == *p ? LIO_RD : LIO_WR;
156     p++;
157     }
158     if ( p == name ) { /* no fd given, find one */
159     for ( fd=0; s->io[fd]; )
160     if ( LSES_FILE_MAX == ++fd )
161     return -ERR_NOMEM;
162     } else if ( s->io[fd] ) { /* close existing */
163     func( s->io[fd], LIO_SCLOSE );
164     /* don't kill the statics :) */
165     if ( s->io[fd] < stdio || s->io[fd] > stdio+2 )
166     mFree( s->io[fd] );
167     }
168     s->io[fd] = (Ios*)mAlloc( func( 0, LIO_SSIZE ) );
169     if ( ! s->io[fd] )
170     return -ERR_NOMEM;
171     s->io[fd]->func = func;
172     s->io[fd]->name = mDup( p, -1 );
173     s->io[fd]->file = flags;
174     return func( s->io[fd], LIO_SOPEN );
175     } /* lses_open */
176    
177    
178    
179     /* ************************************************************
180     public functions
181     */
182    
183     extern Ses *sGet ()
184     {
185     #ifdef _REENTRANT
186     Ses *ses;
187     if ( ! (ses = (Ses*)pthread_getspecific( seskey )) )
188     pthread_setspecific( seskey, ses = cSession( 0 ) );
189     #endif
190     return ses;
191     }
192    
193     extern void sSet ( Ses *s )
194     {
195     #ifndef _REENTRANT
196     ses = s;
197     #else
198     pthread_setspecific( seskey, s );
199     #endif
200     }
201    
202    
203     Ses *cOpen ( Rec *args )
204     {
205     extern void linit();
206    
207     linit();
208     if ( args ) { /* add args */
209     /* TODO: merge args */
210     cses.h.prop = rDup( args, -1, 0 );
211     }
212     return &cses.h;
213     } /* cOpen */
214    
215    
216     Ses *cSession ( Rec *args )
217     {
218     SesI *sesi = 0;
219     Ses *s = 0;
220     int id = 1;
221     /** XXX unless we actually free sessions,
222     we should start checking with maxid
223     or check for expiry
224     */
225     while ( tab[id] )
226     if ( LSES_MAX == ++id )
227     return 0;
228     if ( maxid < id )
229     maxid = id;
230     sesi = tab[id] = (SesI*)malloc( sizeof(SesI) );
231     memset( sesi, 0, sizeof(SesI) );
232     s = &sesi->h;
233     s->id = id;
234     s->hash = -1; /* not hashed (hash is non-negative) */
235     s->prop = args ? rDup( args, -1, 0 ) : 0;
236     /* check props */
237     /* open files */
238     lses_open( s, "2>&2", 0, lio_stdio );
239     return s;
240     } /* cSession */
241    
242    
243     void *mAlloc ( int size )
244     {
245     void *p = memordie( size );
246     memset(p, 0, size);
247     return p;
248     } /* mAlloc */
249    
250    
251     void mFree ( void *mem )
252     {
253     if ( mem )
254     free( mem );
255     } /* mFree */
256    
257    
258     void *mDup ( const void *str, int sz )
259     {
260     void *m = memordie( 0<=sz ? sz : (sz = strlen( str ) + 1) );
261     memcpy( m, str, sz );
262     return m;
263     } /* mDup */
264    
265    
266     int sOpen ( const char *name, int flags, SFunc *type )
267     {
268     SESDECL
269     return lses_open( ses, name, flags, type );
270     } /* sOpen */
271    
272    
273     Ses *openIsisId2Session (int sid) {
274     if (0 > sid || LSES_MAX <= sid || 0 == tab[sid]) {
275     return (Ses*)0;
276     }
277     return &(tab[sid]->h);
278     } /* openIsisId2Session */
279    
280    
281     int openIsisSession2Id (Ses *s) {
282     if (0 == s) {
283     return -1;
284     }
285     return s->id;
286     } /* openIsisSession2Id */
287    
288    
289     Ses *cSesByName ( char *name, int nlen, Tm *now, Tm *expire )
290     {
291     char tbuf[20];
292     int h,i;
293     Ses *s;
294     if ( nlen < 0 )
295     nlen = strlen(name);
296     if ( nlen > 63 )
297     nlen = 63;
298     for ( i=nlen; i--; )
299     if ( !(0xe0 & name[i]) )
300     name[i] = '_';
301     h = lhash( name, nlen );
302     for ( s = htab[h & LSES_MSK]; s; s = s->nxt )
303     if ( h == s->hash
304     && !memcmp( name, s->name, nlen )
305     && !s->name[nlen]
306     ) { /* match */
307     if ( !expire || s->atime.millis >= expire->millis )
308     goto gotit; /* valid */
309     if ( s->cur || s->que ) {
310     log_msg( LOG_WARN, "expired session %d %s still busy!",
311     s->id, s->name );
312     goto gotit; /* valid anyway */
313     }
314     goto refresh;
315     }
316     /* didn't find by name */
317     if ( ! expire ) /* bad thing -- we're going to run out of sessions ... */
318     i = maxid+1;
319     else /* check other expired */
320     for ( i=1; i<=maxid; i++ ) {
321     s = &tab[i]->h; /* sind wir heute defensiv ... */
322     if ( s && s->atime.millis < expire->millis
323     && s->atime.millis && 0 <= s->hash /* else is none of our biz */
324     && !s->cur && !s->que /* else is busy !? */
325     )
326     break;
327     }
328     if ( i > maxid ) {
329     s = cSession( 0 );
330     if ( ! s )
331     return 0;
332     } else /* got one */
333     log_msg( LOG_INFO, "reusing session %d '%s' atime %s",
334     s->id, s->name, s->atime.millis ? timeGtf(tbuf,&s->atime) : "-" );
335     if ( 0 <= s->hash ) { /* was hashed -- unlink */
336     Ses **spp = &htab[s->hash & LSES_MSK];
337     for ( ; *spp; spp = &(*spp)->nxt )
338     if ( s == *spp ) {
339     *spp = s->nxt;
340     break;
341     }
342     }
343     memset( s->name, 0, sizeof(s->name) );
344     memcpy( s->name, name, nlen );
345     s->hash = h;
346     s->nxt = htab[h & LSES_MSK];
347     htab[h & LSES_MSK] = s;
348     refresh:
349     s->ctime.millis = s->mtime.millis = now ? now->millis : 0;
350     s->accnt = 0;
351     if ( s->prop )
352     CLRREC( s->prop );
353     if ( s->res )
354     CLRREC( s->res );
355     gotit:
356     s->atime.millis = now ? now->millis : 0;
357     return s;
358     } /* cSesByName */

  ViewVC Help
Powered by ViewVC 1.1.26