File: threadSvCmd.h

package info (click to toggle)
tclthread 20030827-1
  • links: PTS
  • area: main
  • in suites: sarge
  • size: 1,284 kB
  • ctags: 526
  • sloc: ansic: 4,828; sh: 2,589; tcl: 888; makefile: 240; cpp: 31
file content (200 lines) | stat: -rw-r--r-- 6,436 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
/* 
 * This is the header file for the module that implements shared variables.
 * for protected multithreaded access.
 *
 * Copyright (c) 2002 by Zoran Vasiljevic.
 *
 * See the file "license.txt" for information on usage and redistribution
 * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
 *
 * Rcsid: @(#)$Id: threadSvCmd.h,v 1.9 2002/12/14 11:58:05 vasiljevic Exp $
 * ---------------------------------------------------------------------------
 */

#ifndef _SV_H_
#define _SV_H_

#include <tcl.h>
#include <ctype.h>
#include <string.h>

/*
 * Starting from 8.4 core, Tcl API is CONST'ified
 */

#if (TCL_MAJOR_VERSION == 8) && (TCL_MINOR_VERSION <= 3) 
# define CONST84
#endif

/*
 * Uncomment following line to get command-line
 * compatibility with AOLserver nsv_* commands
 */

/* #define NSV_COMPAT 1 */

/*
 * Uncomment following line to force command-line
 * compatibility with older thread::sv_ commands
 * If you leave it commented-out, the older style
 * command is going to be included in addition to
 * the new tsv::* style.
 */

/* #define OLD_COMPAT 1 */

#ifdef NS_AOLSERVER
# ifdef NSV_COMPAT
#  define N "nsv_"  /* Compatiblity prefix for AOLserver */
# else
#  define N "sv_"   /* Regular command prefix for AOLserver */
# endif
#else
# ifdef OLD_COMPAT
#  define N  "thread::sv_" /* Old command prefix for Tcl */
# else
#  define N  "tsv::" /* Regular command prefix for Tcl */
# endif
#endif

/*
 * This structure is used to simplify interaction with
 * AOLserver. The AOLserver can tune number of shared
 * arrays per bucket, which can be useful when tuning
 * MT-performance of shared arrays. 
 * In AOLserver environment, this structure is filled
 * in by reading server's current configuration.
 * In regular Tcl, we have no easy mechanism for this
 * so we just make it constant (8 buckets).
 */

typedef struct Svconf {
    int numbuckets;
} Svconf;

/*
 * Used when creating arrays/variables
 */

#define FLAGS_CREATEARRAY  1   /* Create the array in bucket if none found */
#define FLAGS_NOERRMSG     2   /* Do not format error message */
#define FLAGS_CREATEVAR    4   /* Create the array variable if none found */

/*
 * The following structure defines a collection of arrays.
 * Only the arrays within a given bucket share a lock, allowing for more
 * concurency.
 */

typedef struct Bucket {
    Tcl_Mutex lock;            /* Lock when accessing arrays in this bucket */
    Tcl_HashTable arrays;      /* Hash table of all arrays in bucket */
    Tcl_HashTable handles;     /* Hash table of given-out handles in bucket */
    struct Container *freeCt;  /* List of free Tcl-object containers */
} Bucket;

/*
 * The following structure maintains the context for each variable array.
 */

typedef struct Array {
    Bucket *bucketPtr;         /* Array bucket. */
    Tcl_HashEntry *entryPtr;   /* Entry in bucket array table. */
    Tcl_HashEntry *handlePtr;  /* Entry in handles table */
    Tcl_HashTable vars;        /* Table of variables. */
} Array;

/*
 * The object container for Tcl-objects stored within shared arrays.
 */

typedef struct Container {
    Bucket *bucketPtr;         /* Bucket holding the array below */
    Array *arrayPtr;           /* Array with the object container*/
    Tcl_HashEntry *entryPtr;   /* Entry in array table. */
    Tcl_HashEntry *handlePtr;  /* Entry in handles table */
    Tcl_Obj *tclObj;           /* Tcl object to hold shared values */
    char *chunkAddr;           /* Address of one chunk of object containers */
    struct Container *nextPtr; /* Next object container in the free list */
} Container;

/*
 * Structure for generating command names in Tcl
 */

typedef struct SvCmdInfo {
    char *name;                 /* The short name of the command */
    char *cmdName;              /* Real (rewritten) name of the command */
    Tcl_ObjCmdProc *objProcPtr; /* The object-based command procedure */
    Tcl_CmdDeleteProc *delProcPtr; /* Pointer to command delete function */
    ClientData clientData;     /* Pointer passed to above command */
    struct SvCmdInfo *nextPtr;  /* Next in chain of registered commands */
} SvCmdInfo;

/*
 * Structure for registering special object duplicator functions.
 * Some regular Tcl object duplicators produce shallow instead of
 * proper deep copies of the object. While this is considered ok
 * in single-threaded apps, a multithreaded app could have problems
 * when accessing objects which live in (i.e. are accessed from) 
 * different interpreters.
 * So, for each object type which should be stored in shared object
 * pools, we must assure that the object is copied properly.
 */

typedef struct RegType {
    Tcl_ObjType *typePtr;       /* Type of the registered object */
    Tcl_DupInternalRepProc *dupIntRepProc; /* Special deep-copy duper */
    struct RegType *nextPtr;    /* Next in chain of registered types */
} RegType;

/*
 * Limited API functions
 */

void Sv_RegisterCommand(char*,Tcl_ObjCmdProc*,Tcl_CmdDeleteProc*,ClientData);
void Sv_RegisterObjType(Tcl_ObjType*, Tcl_DupInternalRepProc*);
int  Sv_Container(Tcl_Interp*,int,Tcl_Obj*CONST objv[],Container**,int*,int);

/*
 * Private version of Tcl_DuplicateObj which takes care about
 * copying objects when loaded to and retrieved from shared array.
 */

Tcl_Obj* Sv_DuplicateObj(Tcl_Obj*);

#define LOCK_BUCKET(a)   if ((a)->lock != (Tcl_Mutex)-1) \
                             Tcl_MutexLock(&(a)->lock)
#define UNLOCK_BUCKET(a) if ((a)->lock != (Tcl_Mutex)-1) \
                             Tcl_MutexUnlock(&(a)->lock)

#define Sv_Lock(a)       if ((a)->bucketPtr->lock != (Tcl_Mutex)-1) \
                             Tcl_MutexLock(&(a)->bucketPtr->lock)
#define Sv_Unlock(a)     if ((a)->bucketPtr->lock != (Tcl_Mutex)-1) \
                             Tcl_MutexUnlock(&(a)->bucketPtr->lock)

#define UnlockArray(a)    if ((a)->bucketPtr->lock != (Tcl_Mutex)-1) \
                             Tcl_MutexUnlock(&((a)->bucketPtr->lock))

/*
 * Needed when copying objects. This is something not exported
 * from Tcl, therefore we must use tricks to get this value.
 * See in sv.c for details.
 */

extern char* tclEmptyStringRep;

#undef  TCL_STORAGE_CLASS
#define TCL_STORAGE_CLASS DLLIMPORT

#endif /* _SV_H_ */

/* EOF $RCSfile: threadSvCmd.h,v $ */

/* Emacs Setup Variables */
/* Local Variables:      */
/* mode: C               */
/* indent-tabs-mode: nil */
/* c-basic-offset: 4     */
/* End:                  */