~ubuntu-branches/ubuntu/karmic/scilab/karmic

« back to all changes in this revision

Viewing changes to pvm3/src/msgbox.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2002-03-21 16:57:43 UTC
  • Revision ID: james.westby@ubuntu.com-20020321165743-e9mv12c1tb1plztg
Tags: upstream-2.6
ImportĀ upstreamĀ versionĀ 2.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
 
 
2
static char rcsid[] =
 
3
        "$Id: msgbox.c,v 1.17 1997/06/27 17:32:30 pvmsrc Exp $";
 
4
 
 
5
/*
 
6
 *         PVM version 3.4:  Parallel Virtual Machine System
 
7
 *               University of Tennessee, Knoxville TN.
 
8
 *           Oak Ridge National Laboratory, Oak Ridge TN.
 
9
 *                   Emory University, Atlanta GA.
 
10
 *      Authors:  J. J. Dongarra, G. E. Fagg, M. Fischer
 
11
 *          G. A. Geist, J. A. Kohl, R. J. Manchek, P. Mucci,
 
12
 *         P. M. Papadopoulos, S. L. Scott, and V. S. Sunderam
 
13
 *                   (C) 1997 All Rights Reserved
 
14
 *
 
15
 *                              NOTICE
 
16
 *
 
17
 * Permission to use, copy, modify, and distribute this software and
 
18
 * its documentation for any purpose and without fee is hereby granted
 
19
 * provided that the above copyright notice appear in all copies and
 
20
 * that both the copyright notice and this permission notice appear in
 
21
 * supporting documentation.
 
22
 *
 
23
 * Neither the Institutions (Emory University, Oak Ridge National
 
24
 * Laboratory, and University of Tennessee) nor the Authors make any
 
25
 * representations about the suitability of this software for any
 
26
 * purpose.  This software is provided ``as is'' without express or
 
27
 * implied warranty.
 
28
 *
 
29
 * PVM version 3 was funded in part by the U.S. Department of Energy,
 
30
 * the National Science Foundation and the State of Tennessee.
 
31
 */
 
32
 
 
33
/*
 
34
 *      msgbox.c
 
35
 *
 
36
 *      Message mailbox database.
 
37
 *
 
38
$Log: msgbox.c,v $
 
39
 * Revision 1.17  1997/06/27  17:32:30  pvmsrc
 
40
 * Updated for WIN32 header files & Authors.
 
41
 *
 
42
 * Revision 1.16  1997/05/07  21:23:54  pvmsrc
 
43
 * Fixed manual packing of class name lengths.
 
44
 *      - no longer necessary with (pvm)upkstralloc() usage.
 
45
 * Fixed bug:
 
46
 *      - only free pattbuf if !pattglob...  D-Oh!
 
47
 *
 
48
 * Revision 1.15  1997/05/05  18:17:49  pvmsrc
 
49
 * Added new pvmregex.o targets (part of ./regex stuff).
 
50
 *      - extracted mb_names() regex usage to new pvm/regex routines:
 
51
 *              void *pvmcompileregex __ProtoGlarp__ (( char * ));
 
52
 *              int pvmmatchregex __ProtoGlarp__ (( void *, char * ));
 
53
 *              void pvmfreeregex __ProtoGlarp__ (( void ** ));
 
54
 *
 
55
 * Revision 1.14  1997/05/02  19:44:38  pvmsrc
 
56
 * Added GNU Regex Stuff:
 
57
 *      - Makefile targets for regex.o
 
58
 *      - usage in mb_names() / msgbox.c
 
59
 *
 
60
 * Revision 1.13  1997/05/02  14:54:18  pvmsrc
 
61
 * Implemented guts of pvm_getmboxinfo():
 
62
 *      - user library side sends pattern & receives back / allocs array.
 
63
 *      - at pvmd side mb_names() searches class list for matching pattern,
 
64
 *              count up # of entries, and pack up struct info.
 
65
 *              (Note:  does not yet use GNU regex stuff...)
 
66
 *
 
67
 * Revision 1.12  1997/04/10  17:53:54  pvmsrc
 
68
 * Externalized me_new()...
 
69
 *      - for WT_RECVINFO usage...
 
70
 *
 
71
 * Revision 1.11  1997/04/08  20:06:33  pvmsrc
 
72
 * Un-static-ed me_free().
 
73
 *      - so ddpro.c can use it...  D-Oh.
 
74
 *
 
75
 * Revision 1.10  1997/04/08  19:57:52  pvmsrc
 
76
 * Promoted mbox static "classes" to public global "pvmmboxclasses".
 
77
 *      - so pvmd can spank mboxes in ddpro.c...  :-Q
 
78
 *      - renamed everywhere, moved decl / extern to global.[ch].
 
79
 *
 
80
 * Revision 1.9  1997/04/08  19:41:11  pvmsrc
 
81
 * Added me_savetid to pvmmentry struct.
 
82
 *      - for keeping track of original owner on persistent mboxes.
 
83
 *      - allows more careful cleanup in a system reset, set me_tid to 0
 
84
 *              but save original tid in me_savetid first...  :-)
 
85
 *
 
86
 * Revision 1.8  1997/04/08  18:45:20  pvmsrc
 
87
 * Yanked out internal struct defns for mclass & mentry.
 
88
 *      - replaced with msgbox.h header, and pvmmclass / pvmmentry structs.
 
89
 *
 
90
 * Revision 1.7  1997/04/08  17:53:25  pvmsrc
 
91
 * Added new mb_tidy_reset() routine.
 
92
 *      - triggered by task exit during a system reset (when persistent
 
93
 *              mbox entries are owned by task).
 
94
 *      - clear out any persistent mboxes owned by task, or any others
 
95
 *              that have already been cleared.
 
96
 *
 
97
 * Revision 1.6  1997/04/01  16:39:39  pvmsrc
 
98
 * Oops...  PvmMboxOverwritable -> PvmMboxOverWritable...  D-Oh.
 
99
 *
 
100
 * Revision 1.5  1997/04/01  16:19:25  pvmsrc
 
101
 * Modified mbox internals to properly handle new flags syntax.
 
102
 *      - pvm_putinfo():
 
103
 *              * PvmMboxMultiInstance = if index 0 is in use, stick in
 
104
 *                      first available higher index.
 
105
 *              * PvmMboxOverwritable = allow anyone to overwrite or delete
 
106
 *                      the given mbox entry.
 
107
 *              * PvmMboxPersistent = do not remove mailbox on task exit,
 
108
 *                      allow only PVMD to delete on reset (after task exit only).
 
109
 *      - pvm_recvinfo():
 
110
 *              * PvmMboxReadAndDelete = if entry is owned by task or is
 
111
 *                      overwritable, read entry and atomically delete, else fail.
 
112
 *              * PvmMboxFirstAvail = if entry not present at given index,
 
113
 *                      return next entry by index, else fail.
 
114
 *
 
115
 * Revision 1.4  1997/01/28  19:26:54  pvmsrc
 
116
 * New Copyright Notice & Authors.
 
117
 *
 
118
 * Revision 1.3  1996/10/24  21:04:48  pvmsrc
 
119
 * Moved #include of "global.h" down below other headers:
 
120
 *      - need to have all of the structures / types declared before
 
121
 *              the globals can be declared...
 
122
 *
 
123
 * Revision 1.2  1996/09/23  23:32:16  pvmsrc
 
124
 * Initial Creation - original msgbox.c.
 
125
 *
 
126
 */
 
127
 
 
128
 
 
129
#include <stdio.h>
 
130
#ifdef NEEDMENDIAN
 
131
#include <machine/endian.h>
 
132
#endif
 
133
#ifdef NEEDENDIAN
 
134
#include <endian.h>
 
135
#endif
 
136
#ifdef NEEDSENDIAN
 
137
#include <sys/endian.h>
 
138
#endif
 
139
#ifndef WIN32
 
140
#include <rpc/types.h>
 
141
#include <rpc/xdr.h>
 
142
#else 
 
143
#include "..\xdr\types.h"
 
144
#include "..\xdr\xdr.h"
 
145
#endif
 
146
 
 
147
#ifdef  SYSVSTR
 
148
#include <string.h>
 
149
#else
 
150
#include <strings.h>
 
151
#endif
 
152
#include <pvm3.h>
 
153
#include "pvmalloc.h"
 
154
#include "listmac.h"
 
155
#include "pmsg.h"
 
156
#include "msgbox.h"
 
157
#include "global.h"
 
158
 
 
159
void *pvmcompileregex __ProtoGlarp__ (( char * ));
 
160
int pvmmatchregex __ProtoGlarp__ (( void *, char * ));
 
161
void pvmfreeregex __ProtoGlarp__ (( void ** ));
 
162
 
 
163
 
 
164
/***************
 
165
 **  Globals  **
 
166
 **           **
 
167
 ***************/
 
168
 
 
169
extern int pvmdebmask;                                  /* from pvmd.c */
 
170
 
 
171
/***************
 
172
 **  Private  **
 
173
 **           **
 
174
 ***************/
 
175
 
 
176
struct pvmmentry *
 
177
me_new(ind)
 
178
        int ind;
 
179
{
 
180
        struct pvmmentry *ep;
 
181
 
 
182
        if (ep = TALLOC(1, struct pvmmentry, "pvmmentry")) {
 
183
                ep->me_link = ep->me_rlink = ep;
 
184
                ep->me_tid = 0;
 
185
                ep->me_savetid = 0;
 
186
                ep->me_flags = PvmMboxDefault;
 
187
                ep->me_msg = 0;
 
188
                ep->me_ind = ind;
 
189
        }
 
190
        return ep;
 
191
}
 
192
 
 
193
 
 
194
static struct pvmmclass *
 
195
mc_new(name)
 
196
        char *name;
 
197
{
 
198
        struct pvmmclass *np;
 
199
 
 
200
        if (np = TALLOC(1, struct pvmmclass, "pvmmclass")) {
 
201
                if (name) {
 
202
                        np->mc_name = STRALLOC(name);
 
203
                        np->mc_ent = me_new(-1);
 
204
                        LISTPUTBEFORE(pvmmboxclasses, np, mc_link, mc_rlink);
 
205
 
 
206
                } else {
 
207
                        np->mc_link = np->mc_rlink = np;
 
208
                        np->mc_name = 0;
 
209
                        np->mc_ent = 0;
 
210
                }
 
211
        }
 
212
        return np;
 
213
}
 
214
 
 
215
 
 
216
int
 
217
me_free(np, ep)
 
218
        struct pvmmclass *np;
 
219
        struct pvmmentry *ep;
 
220
{
 
221
        LISTDELETE(ep, me_link, me_rlink);
 
222
        pmsg_unref(ep->me_msg);
 
223
        PVM_FREE(ep);
 
224
        if (np->mc_ent->me_link == np->mc_ent) {
 
225
                LISTDELETE(np, mc_link, mc_rlink);
 
226
                PVM_FREE(np->mc_name);
 
227
                PVM_FREE(np->mc_ent);
 
228
                PVM_FREE(np);
 
229
        }
 
230
        return 0;
 
231
}
 
232
 
 
233
 
 
234
static struct pvmmclass *
 
235
mc_find(name)
 
236
        char *name;
 
237
{
 
238
        struct pvmmclass *np;
 
239
 
 
240
        for (np = pvmmboxclasses->mc_link; np != pvmmboxclasses;
 
241
                        np = np->mc_link)
 
242
                if (!strcmp(np->mc_name, name))
 
243
                        return np;
 
244
        return (struct pvmmclass *)0;
 
245
}
 
246
 
 
247
 
 
248
int
 
249
mb_init()
 
250
{
 
251
        pvmmboxclasses = mc_new((char*)0);
 
252
        return 0;
 
253
}
 
254
 
 
255
 
 
256
int
 
257
mb_insert(tid, name, req, flags, mp)
 
258
        int tid;                                /* owner task */
 
259
        char *name;                             /* class name */
 
260
        int req;                                /* index requested or -1 for lowest avail */
 
261
        int flags;
 
262
        struct pmsg *mp;                /* message to store */
 
263
{
 
264
        struct pvmmclass *np;
 
265
        struct pvmmentry *ep;
 
266
        struct pvmmentry *ep2 = 0;
 
267
 
 
268
        if (!(np = mc_find(name)))
 
269
                if (!(np = mc_new(name)))
 
270
                        return PvmNoMem;
 
271
 
 
272
        for (ep = np->mc_ent->me_link; ep != np->mc_ent; ep = ep->me_link)
 
273
                if (ep->me_ind >= req)
 
274
                        break;
 
275
 
 
276
        /* default insert is "locked"... */
 
277
 
 
278
        if (flags & PvmMboxMultiInstance) {
 
279
                for (; ep != np->mc_ent; ep = ep->me_link) {
 
280
                        if (ep->me_ind != req)
 
281
                                break;
 
282
                        if ( (ep->me_flags & PvmMboxOverWritable)
 
283
                                        || tid == ep->me_tid ) {
 
284
                                ep2 = ep;
 
285
                                break;
 
286
                        }
 
287
                        req = ep->me_ind + 1;
 
288
                }
 
289
        } else {
 
290
                if (ep->me_ind == req) {
 
291
                        if ( !(ep->me_flags & PvmMboxOverWritable)
 
292
                                        && tid != ep->me_tid) {
 
293
                                return PvmDenied;
 
294
                        }
 
295
                        ep2 = ep;
 
296
                }
 
297
        }
 
298
 
 
299
        if (ep2) {
 
300
                ep = ep2->me_link;
 
301
                LISTDELETE(ep2, me_link, me_rlink);
 
302
                pmsg_unref(ep2->me_msg);
 
303
                PVM_FREE(ep2);
 
304
        }
 
305
        ep2 = me_new(req);
 
306
        ep2->me_tid = tid;
 
307
        ep2->me_flags = flags;
 
308
        ep2->me_msg = mp;
 
309
        LISTPUTBEFORE(ep, ep2, me_link, me_rlink);
 
310
 
 
311
        return req;
 
312
}
 
313
 
 
314
 
 
315
int
 
316
mb_delete(tid, name, req, flags)
 
317
        int tid;                                /* owner task */
 
318
        char *name;                             /* class name */
 
319
        int req;                                /* index */
 
320
        int flags;                              /* options */
 
321
{
 
322
        struct pvmmclass *np;
 
323
        struct pvmmentry *ep = 0;
 
324
 
 
325
        if (np = mc_find(name)) {
 
326
                for (ep = np->mc_ent->me_link; ep != np->mc_ent;
 
327
                                ep = ep->me_link) {
 
328
                        if (ep->me_ind == req)
 
329
                                break;
 
330
                }
 
331
                if (ep == np->mc_ent)
 
332
                        ep = 0;
 
333
        }
 
334
 
 
335
        if (!ep)
 
336
                return PvmNotFound;
 
337
 
 
338
        if ( !(ep->me_flags & PvmMboxOverWritable) && tid != ep->me_tid )
 
339
                return PvmDenied;
 
340
 
 
341
        req = ep->me_ind;
 
342
        me_free(np, ep);
 
343
 
 
344
        return req;
 
345
}
 
346
 
 
347
 
 
348
int
 
349
mb_lookup(tid, name, req, flags, mpp)
 
350
        int tid;                                /* owner task */
 
351
        char *name;                             /* class name */
 
352
        int req;                                /* index requested or -1 for first avail */
 
353
        int flags;
 
354
        struct pmsg **mpp;              /* message return */
 
355
{
 
356
        struct pvmmclass *np;
 
357
        struct pvmmentry *ep = 0;
 
358
 
 
359
        if (np = mc_find(name)) {
 
360
                for (ep = np->mc_ent->me_link; ep != np->mc_ent;
 
361
                                ep = ep->me_link) {
 
362
                        if (ep->me_ind >= req)
 
363
                                break;
 
364
                }
 
365
                if (ep == np->mc_ent)
 
366
                        ep = 0;
 
367
                else if (!(flags & PvmMboxFirstAvail) && ep->me_ind != req)
 
368
                        ep = 0;
 
369
        }
 
370
 
 
371
        if (ep) {
 
372
                if ( flags & PvmMboxReadAndDelete ) {
 
373
                        if ( (ep->me_flags & PvmMboxOverWritable)
 
374
                                        || tid == ep->me_tid ) {
 
375
                                req = ep->me_ind;
 
376
                                ep->me_msg->m_ref++;
 
377
                                *mpp = ep->me_msg;
 
378
                                me_free(np, ep);
 
379
                        } else {
 
380
                                req = PvmDenied;
 
381
                                *mpp = (struct pmsg *) NULL;
 
382
                        }
 
383
                } else {
 
384
                        req = ep->me_ind;
 
385
                        ep->me_msg->m_ref++;
 
386
                        *mpp = ep->me_msg;
 
387
                }
 
388
        } else
 
389
                req = PvmNotFound;
 
390
 
 
391
        return req;
 
392
}
 
393
 
 
394
 
 
395
int
 
396
mb_names(tid, pattern, mp)
 
397
        int tid;
 
398
        char *pattern;
 
399
        struct pmsg *mp;
 
400
{
 
401
        void *pattbuff;
 
402
 
 
403
        struct pvmmclass *np;
 
404
        struct pvmmentry *ep;
 
405
 
 
406
        int pattglob = 0;
 
407
        int cnt;
 
408
 
 
409
        /* Check for "*" Global Match Pattern */
 
410
 
 
411
        if ( !strcmp( pattern, "*" ) )
 
412
                pattglob = 1;
 
413
 
 
414
        /* Compile Regular Expression */
 
415
 
 
416
        if ( !pattglob )
 
417
                pattbuff = pvmcompileregex( pattern );
 
418
 
 
419
        /* Count # of Classes */
 
420
 
 
421
        cnt = 0;
 
422
 
 
423
        for ( np = pvmmboxclasses->mc_link; np != pvmmboxclasses;
 
424
                        np = np->mc_link )
 
425
        {
 
426
                if ( pattglob
 
427
                                || ( ( pattbuff ) ?
 
428
                                        ( pvmmatchregex( pattbuff, np->mc_name ) )
 
429
                                        : ( !strcmp( pattern, np->mc_name ) ) ) )
 
430
                {
 
431
                        cnt++;
 
432
                }
 
433
        }
 
434
 
 
435
        pkint( mp, cnt );
 
436
 
 
437
        /* Pack Class Info */
 
438
 
 
439
        for ( np = pvmmboxclasses->mc_link; np != pvmmboxclasses;
 
440
                        np = np->mc_link )
 
441
        {
 
442
                if ( pattglob
 
443
                                || ( ( pattbuff ) ?
 
444
                                        ( pvmmatchregex( pattbuff, np->mc_name ) )
 
445
                                        : ( !strcmp( pattern, np->mc_name ) ) ) )
 
446
                {
 
447
                        pkstr( mp, np->mc_name );
 
448
 
 
449
                        /* Count # of Entries */
 
450
 
 
451
                        cnt = 0;
 
452
 
 
453
                        for ( ep = np->mc_ent->me_link; ep != np->mc_ent;
 
454
                                        ep = ep->me_link )
 
455
                                cnt++;
 
456
 
 
457
                        pkint( mp, cnt );
 
458
 
 
459
                        /* Pack Entry Info */
 
460
 
 
461
                        for ( ep = np->mc_ent->me_link; ep != np->mc_ent;
 
462
                                        ep = ep->me_link )
 
463
                        {
 
464
                                pkint( mp, ep->me_ind );
 
465
                                pkint( mp, ep->me_tid );
 
466
                                pkint( mp, ep->me_flags );
 
467
                        }
 
468
                }
 
469
        }
 
470
 
 
471
        if ( !pattglob && pattbuff )
 
472
                pvmfreeregex( &pattbuff );
 
473
 
 
474
        return 0;
 
475
}
 
476
 
 
477
 
 
478
int
 
479
mb_dump(np)
 
480
        struct pvmmclass *np;
 
481
{
 
482
        struct pvmmentry *ep;
 
483
 
 
484
        pvmlogprintf("<%s>\n", np->mc_name);
 
485
        for (ep = np->mc_ent->me_link; ep != np->mc_ent; ep = ep->me_link) {
 
486
                pvmlogprintf("%d (0x%x): owner 0x%x (was 0x%x) flags %d\n",
 
487
                                ep->me_ind, ep->me_ind, ep->me_tid, ep->me_savetid,
 
488
                                ep->me_flags);
 
489
                pmsg_dump(ep->me_msg, 2);
 
490
        }
 
491
        return 0;
 
492
}
 
493
 
 
494
 
 
495
int
 
496
mb_dumpall()
 
497
{
 
498
        struct pvmmclass *np;
 
499
 
 
500
        pvmlogerror("mb_dumpall():\n");
 
501
        for (np = pvmmboxclasses->mc_link; np != pvmmboxclasses;
 
502
                        np = np->mc_link)
 
503
                mb_dump(np);
 
504
        return 0;
 
505
}
 
506
 
 
507
 
 
508
/*      mb_tidy()
 
509
*
 
510
*       Task has exited.
 
511
*       Remove any non-sticky entries owned by it.
 
512
*       Remove its tid as owner for sticky entries and reset Lock.
 
513
*/
 
514
 
 
515
int
 
516
mb_tidy(tid)
 
517
        int tid;
 
518
{
 
519
        struct pvmmclass *np, *np2;
 
520
        struct pvmmentry *ep, *ep2;
 
521
 
 
522
        if (!tid)
 
523
                return 0;
 
524
 
 
525
        if (pvmdebmask & PDMMBOX)
 
526
                pvmlogprintf("mb_tidy() tid 0x%x\n", tid);
 
527
 
 
528
        for (np = pvmmboxclasses->mc_link; np != pvmmboxclasses; np = np2) {
 
529
                np2 = np->mc_link;
 
530
                for (ep = np->mc_ent->me_link; ep != np->mc_ent; ep = ep2) {
 
531
                        ep2 = ep->me_link;
 
532
                        if (ep->me_tid == tid) {
 
533
                                if (ep->me_flags & PvmMboxPersistent) {
 
534
                                        ep->me_savetid = ep->me_tid;
 
535
                                        ep->me_tid = 0;
 
536
                                } else {
 
537
                                        me_free(np, ep);
 
538
                                        if (np2->mc_rlink != np)
 
539
                                                break;
 
540
                                }
 
541
                        }
 
542
                }
 
543
        }
 
544
        return 0;
 
545
}
 
546
 
 
547
 
 
548
/*      mb_tidy_reset()
 
549
*
 
550
*       Task has exited during a system reset.
 
551
*       Remove any persistent entries owned by it, and any other
 
552
*       persistent entries that have already been cleared.
 
553
*/
 
554
 
 
555
int
 
556
mb_tidy_reset(tid)
 
557
        int tid;
 
558
{
 
559
        struct pvmmclass *np, *np2;
 
560
        struct pvmmentry *ep, *ep2;
 
561
 
 
562
        if (!tid)
 
563
                return 0;
 
564
 
 
565
        if (pvmdebmask & PDMMBOX)
 
566
                pvmlogprintf("mb_tidy_reset() tid 0x%x\n", tid);
 
567
 
 
568
        for (np = pvmmboxclasses->mc_link; np != pvmmboxclasses; np = np2) {
 
569
                np2 = np->mc_link;
 
570
                for (ep = np->mc_ent->me_link; ep != np->mc_ent; ep = ep2) {
 
571
                        ep2 = ep->me_link;
 
572
                        /* mb_tidy() & mb_tidy_reset() could be in any order... */
 
573
                        if ( (ep->me_flags & PvmMboxPersistent)
 
574
                                        && ( ep->me_tid == tid
 
575
                                                || (!(ep->me_tid) && ep->me_savetid == tid) ) )
 
576
                        {
 
577
                                me_free(np, ep);
 
578
                                if (np2->mc_rlink != np)
 
579
                                        break;
 
580
                        }
 
581
                }
 
582
        }
 
583
        return 0;
 
584
}
 
585