Changeset 17390
- Timestamp:
- Apr 8, 2008, 4:15:02 AM (18 years ago)
- File:
-
- 1 edited
-
trunk/Ohana/src/opihi/lib.shell/gprint.c (modified) (15 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/Ohana/src/opihi/lib.shell/gprint.c
r17069 r17390 25 25 pointer is closed and set to NULL. setting a new FILE results in the 26 26 IObuffer being freed and an already opened FILE to be flushed and closed. 27 28 29 gprint & mutex: 30 31 gprintInit : init_stream_mutex 32 gprintGetStream : init_stream_mutex 33 gprintCloseFile : init_stream_mutex 34 35 gprintSetFileAllThreads : set_file_mutex 36 (gprintSetFile -> gprintCloseFile) 37 38 gprintSetFileThisThread : set_file_mutex 39 (gprintGetStream) 40 (gprintSetFile -> gprintCloseFile) 41 42 we are safe from dead locks: init_stream_mutex can be wrapped by set_file_mutex, but 43 not vice-versa 44 27 45 */ 28 46 29 static gpStream * streams = NULL;47 static gpStream **streams = NULL; 30 48 static int Nstreams = 0; 31 49 32 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;50 static pthread_mutex_t init_stream_mutex = PTHREAD_MUTEX_INITIALIZER; 33 51 34 52 void gprintInit () { … … 38 56 39 57 /* need to use a mutex to prevent two threads from initing simultaneously */ 40 pthread_mutex_lock (&mutex); 41 58 pthread_mutex_lock (&init_stream_mutex); 59 60 // streams is an array of pointers so we can add more streams without changing pointers 42 61 if (streams == NULL) { 43 62 Nstreams = 2; 44 ALLOCATE (streams, gpStream , Nstreams);63 ALLOCATE (streams, gpStream *, Nstreams); 45 64 } else { 46 65 Nstreams += 2; 47 REALLOCATE (streams, gpStream , Nstreams);66 REALLOCATE (streams, gpStream *, Nstreams); 48 67 } 49 68 … … 52 71 53 72 N = Nstreams - 2; 54 streams[N].dest = GP_LOG; 55 streams[N].file = stdout; 56 streams[N].name = strcreate ("stdout"); 57 58 ALLOCATE (streams[N].buffer, IOBuffer, 1); 59 InitIOBuffer (streams[N].buffer, 64); 60 streams[N].mode = GP_FILE; 61 streams[N].thread = id; 73 ALLOCATE (streams[N], gpStream, 1); 74 streams[N][0].dest = GP_LOG; 75 streams[N][0].file = stdout; 76 streams[N][0].name = strcreate ("stdout"); 77 78 ALLOCATE (streams[N][0].buffer, IOBuffer, 1); 79 InitIOBuffer (streams[N][0].buffer, 64); 80 streams[N][0].mode = GP_FILE; 81 streams[N][0].thread = id; 62 82 63 83 N = Nstreams - 1; 64 streams[N].dest = GP_ERR; 65 streams[N].file = stderr; 66 streams[N].name = strcreate ("stderr"); 67 68 ALLOCATE (streams[N].buffer, IOBuffer, 1); 69 InitIOBuffer (streams[N].buffer, 64); 70 streams[N].mode = GP_FILE; 71 streams[N].thread = id; 72 73 pthread_mutex_unlock (&mutex); 84 ALLOCATE (streams[N], gpStream, 1); 85 streams[N][0].dest = GP_ERR; 86 streams[N][0].file = stderr; 87 streams[N][0].name = strcreate ("stderr"); 88 89 ALLOCATE (streams[N][0].buffer, IOBuffer, 1); 90 InitIOBuffer (streams[N][0].buffer, 64); 91 streams[N][0].mode = GP_FILE; 92 streams[N][0].thread = id; 93 94 pthread_mutex_unlock (&init_stream_mutex); 74 95 } 75 96 … … 78 99 int i; 79 100 pthread_t id; 101 gpStream *stream; 102 103 // need to wait for initialization to be finished before getting stream or the array 104 // (streams[i]) may move 105 pthread_mutex_lock (&init_stream_mutex); 80 106 81 107 id = pthread_self(); … … 83 109 /* find the existing output stream which matches */ 84 110 for (i = 0; i < Nstreams; i++) { 85 if (streams[i].dest != dest) continue; 86 if (!pthread_equal (streams[i].thread, id)) continue; 87 return (&streams[i]); 88 } 111 if (streams[i][0].dest != dest) continue; 112 if (!pthread_equal (streams[i][0].thread, id)) continue; 113 stream = streams[i]; 114 pthread_mutex_unlock (&init_stream_mutex); 115 return stream; 116 } 117 pthread_mutex_unlock (&init_stream_mutex); 89 118 fprintf (stderr, "programming error: gprintInit not called for thread\n"); 90 119 abort (); … … 115 144 } 116 145 146 // we cannot do the operation below while another thread is initing 147 pthread_mutex_lock (&init_stream_mutex); 148 117 149 // must we close the existing file? if still being used, then no 118 150 Nmatch = 0; 119 151 for (i = 0; i < Nstreams; i++) { 120 if (stream == &streams[i]) continue; 121 if (streams[i].file == stream[0].file) Nmatch ++; 122 } 152 if (stream == streams[i]) continue; 153 if (streams[i][0].file == stream[0].file) Nmatch ++; 154 } 155 pthread_mutex_unlock (&init_stream_mutex); 156 123 157 if (Nmatch == 0) { 124 158 fflush (stream[0].file); … … 130 164 } 131 165 166 // this thread only operates on its own stream 132 167 void gprintSetBuffer (gpDest dest) { 133 168 … … 145 180 } 146 181 182 // this thread only operates on its own stream 147 183 IOBuffer *gprintGetBuffer (gpDest dest) { 148 184 … … 158 194 int i; 159 195 160 / * need to use a mutex to prevent two threads from initing simultaneously */196 // be sure we are not colliding with gprintSetFileThisThread 161 197 pthread_mutex_lock (&set_file_mutex); 162 198 163 199 for (i = 0; i < Nstreams; i++) { 164 if (streams[i] .dest != dest) continue;165 gprintSetFile ( &streams[i], dest, filename);200 if (streams[i][0].dest != dest) continue; 201 gprintSetFile (streams[i], dest, filename); 166 202 } 167 203 … … 170 206 } 171 207 208 // this thread only operates on its own stream 172 209 void gprintSetFileThisThread (gpDest dest, char *filename) { 173 210 174 211 gpStream *stream; 175 stream = gprintGetStream (dest); 176 177 /* need to use a mutex to prevent two threads from initing simultaneously */ 212 213 // be sure we are not colliding with gprintSetFileAllThreads 178 214 pthread_mutex_lock (&set_file_mutex); 179 215 216 stream = gprintGetStream (dest); 180 217 gprintSetFile (stream, dest, filename); 181 218 … … 183 220 return; 184 221 } 185 186 222 187 223 void gprintSetFile (gpStream *stream, gpDest dest, char *filename) { … … 231 267 } 232 268 269 // this thread only operates on its own stream 233 270 FILE *gprintGetFile (gpDest dest) { 234 271 … … 238 275 } 239 276 277 // this thread only operates on its own stream 240 278 char *gprintGetName (gpDest dest) { 241 279 … … 251 289 va_list argp; 252 290 291 // this thread only writes to its own stream 253 292 stream = gprintGetStream (dest); 254 293 … … 273 312 gpStream *stream; 274 313 314 // this thread only writes to its own stream 275 315 stream = gprintGetStream (dest); 276 316
Note:
See TracChangeset
for help on using the changeset viewer.
