Ticket #256: stream_panic.4.diff
File stream_panic.4.diff, 20.8 KB (added by , 12 years ago) |
---|
-
src/emx/include/emx/io.h
237 237 { 238 238 if (!stream_validate(stream)) 239 239 return 0; 240 if ( !(stream->_flags & _IOLOCKED) 241 || !_fmutex_is_owner(&stream->__u.__fsem)) 240 if (!_fmutex_is_owner(&stream->__u.__fsem)) 242 241 { 243 242 if (_fmutex_request(&stream->__u.__fsem, _FMR_IGNINT) != 0) 244 243 { 245 244 __stream_abort(stream, "fmutex_request failed"); 246 245 return 0; 247 246 } 248 stream->_flags = 0x01000000 | (stream->_flags & ~_IOLOCKED); 247 if ((stream->_flags & _IOLOCKED)) 248 { 249 __stream_abort(stream, "lock, count not 0"); 250 return 0; 251 } 249 252 } 250 253 else 251 stream->_flags = ((stream->_flags & _IOLOCKED) + 0x01000000) | (stream->_flags & ~_IOLOCKED); 254 { 255 if ((stream->_flags & _IOLOCKED) == _IOLOCKED) 256 { 257 __stream_abort(stream, "lock, count overflow"); 258 return 0; 259 } 260 } 261 stream->_flags = ((stream->_flags & _IOLOCKED) + 0x01000000) | (stream->_flags & ~_IOLOCKED); 252 262 return 1; 253 263 } 254 264 … … 256 266 { 257 267 if (!stream_validate(stream)) 258 268 return 0; 259 if ( !(stream->_flags & _IOLOCKED) 260 || !_fmutex_is_owner(&stream->__u.__fsem)) 269 if (!_fmutex_is_owner(&stream->__u.__fsem)) 261 270 { 262 271 if (_fmutex_request(&stream->__u.__fsem, _FMR_NOWAIT) != 0) 263 272 { 264 273 __stream_abort(stream, "fmutex_request failed"); 265 274 return 0; 266 275 } 267 stream->_flags = 0x01000000 | (stream->_flags & ~_IOLOCKED); 276 if ((stream->_flags & _IOLOCKED)) 277 { 278 __stream_abort(stream, "lock, count not 0"); 279 return 0; 280 } 268 281 } 269 282 else 270 stream->_flags = ((stream->_flags & _IOLOCKED) + 0x01000000) | (stream->_flags & ~_IOLOCKED); 283 { 284 if ((stream->_flags & _IOLOCKED) == _IOLOCKED) 285 { 286 __stream_abort(stream, "lock, count overflow"); 287 return 0; 288 } 289 } 290 stream->_flags = ((stream->_flags & _IOLOCKED) + 0x01000000) | (stream->_flags & ~_IOLOCKED); 271 291 return 1; 272 292 } 273 293 … … 275 295 { 276 296 if (!stream_validate(stream)) 277 297 return 0; 278 if (!(stream->_flags & _IOLOCKED))279 {280 __stream_abort(stream, "unlock, 0 count");281 return 0;282 }283 298 #ifdef __LIBC_STRICT 284 299 if (!_fmutex_is_owner(&stream->__u.__fsem)) 285 300 { … … 287 302 return 0; 288 303 } 289 304 #endif 305 if (!(stream->_flags & _IOLOCKED)) 306 { 307 __stream_abort(stream, "unlock, 0 count"); 308 return 0; 309 } 290 310 stream->_flags = ((stream->_flags & _IOLOCKED) - 0x01000000) | (stream->_flags & ~_IOLOCKED); 291 311 if ( !(stream->_flags & _IOLOCKED) 292 312 && _fmutex_release(&stream->__u.__fsem) != 0) … … 302 322 #define STREAM_LOCK_NOWAIT(f) stream_trylock(f) 303 323 #define STREAM_UNLOCKED(f) ((f)->__uVersion == _FILE_STDIO_VERSION && _fmutex_available(&(f)->__u.__fsem)) 304 324 325 typedef struct __STREAM_XCPTREGREC 326 { 327 void *apv[2]; // EXCEPTIONREGISTRATIONRECORD 328 struct __sFILE *file; 329 unsigned fs; 330 } __STREAM_XCPTREGREC, *__STREAM_PXCPTREGREC; 331 332 void __stream_xcpt_init(__STREAM_PXCPTREGREC pRegRec); 333 void __stream_xcpt_done(__STREAM_PXCPTREGREC pRegRec); 334 335 #define STREAM_XCPT_BEGIN { __STREAM_XCPTREGREC __stream_xcptregec; __stream_xcpt_init(&__stream_xcptregec); 336 #define STREAM_XCPT_END __stream_xcpt_done(&__stream_xcptregec); } 337 338 #define STREAM_XCPT_LOCK(f) do { __stream_xcptregec.file = f; stream_lock(f); } while (0) 339 #define STREAM_XCPT_UNLOCK(f) do { stream_unlock(f); __stream_xcptregec.file = NULL; } while (0) 340 #define STREAM_XCPT_LOCK_NOWAIT(f) (stream_trylock(f) ? (__stream_xcptregec.file = f, 1) : 0) 341 #define STREAM_XCPT_UNLOCK_END(f) do { stream_unlock(f); __stream_xcptregec.file = NULL; __stream_xcpt_done(&__stream_xcptregec); } while (0) 342 #define STREAM_XCPT_NOLOCK_END() do { __stream_xcpt_done(&__stream_xcptregec); } while(0) 343 305 344 #endif /* __FILE_FSEM_DECLARED */ 306 345 307 346 struct __libc_FileHandle; -
src/emx/src/lib/app/stdio.c
1 1 /* stdio.c (emx+gcc) -- Copyright (c) 1990-1996 by Eberhard Mattes 2 2 -- Copyright (c) 2003-2004 by knut st. osmundsen */ 3 3 4 #define INCL_DOSEXCEPTIONS 5 #include <os2emx.h> 6 4 7 #include "libc-alias.h" 5 8 #include <sys/builtin.h> /* For <sys/fmutex.h> */ 6 9 #include <sys/fmutex.h> … … 157 160 _CRT_EXIT1(_exit_streams) 158 161 159 162 163 #if defined (__FILE_FSEM_DECLARED) 160 164 161 165 /** 162 166 * Fatal stream error. … … 180 184 return 0; 181 185 } 182 186 187 /** 188 * Exception handler for STREAM_XCPT_LOCK()/STREAM_XCPT_UNLOCK(). 189 * 190 * Releases the stream lock on thread termination. 191 */ 192 ULONG __stream_exception(EXCEPTIONREPORTRECORD *report, 193 EXCEPTIONREGISTRATIONRECORD *registration, 194 CONTEXTRECORD *context, 195 void *dummy); 196 ULONG __stream_exception(EXCEPTIONREPORTRECORD *report, 197 EXCEPTIONREGISTRATIONRECORD *registration, 198 CONTEXTRECORD *context, 199 void *dummy) 200 { 201 __STREAM_PXCPTREGREC pRegRec = (__STREAM_PXCPTREGREC)registration; 202 203 if (report->fHandlerFlags & EH_UNWINDING) 204 { 205 if (pRegRec->file) 206 { 207 // make sure we won't be called again 208 DosUnsetExceptionHandler(registration); 209 // unlock the stream mutex (note that there is a hole between 210 // unlocking and resetting pRegRec->file so check lock state first) 211 if (!STREAM_UNLOCKED(pRegRec->file)) 212 STREAM_UNLOCK(pRegRec->file); 213 } 214 } 215 return XCPT_CONTINUE_SEARCH; 216 } 217 218 void __stream_xcpt_init(__STREAM_PXCPTREGREC pRegRec) 219 { 220 __asm__ __volatile__ ("movl %%fs, %%eax; movl %%eax,%0; movl $DosTIB, %%eax; movl %%eax, %%fs" : : "m" (pRegRec->fs) : "%eax" ); 221 222 ((PEXCEPTIONREGISTRATIONRECORD)pRegRec)->prev_structure = 0; 223 ((PEXCEPTIONREGISTRATIONRECORD)pRegRec)->ExceptionHandler = __stream_exception; 224 pRegRec->file = 0; 225 DosSetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)pRegRec); 226 } 227 228 void __stream_xcpt_done(__STREAM_PXCPTREGREC pRegRec) 229 { 230 DosUnsetExceptionHandler((PEXCEPTIONREGISTRATIONRECORD)pRegRec); 231 232 __asm__ __volatile__ ("movl %0, %%eax; movl %%eax,%%fs;" : : "m" (pRegRec->fs) : "%eax" ); 233 } 234 235 #endif /* __FILE_FSEM_DECLARED */ -
src/emx/src/lib/io/fflush.c
79 79 return result; 80 80 } 81 81 82 STREAM_LOCK (stream); 82 STREAM_XCPT_BEGIN 83 84 STREAM_XCPT_LOCK (stream); 83 85 result = fflush_unlocked (stream); 84 STREAM_UNLOCK (stream); 86 STREAM_XCPT_UNLOCK (stream); 87 88 STREAM_XCPT_END 89 85 90 return result; 86 91 } -
src/emx/src/lib/io/fgetc.c
15 15 16 16 int _STD(fgetc)(FILE *stream) 17 17 { 18 STREAM_LOCK(stream); 19 int rc = _getc_inline(stream); 20 STREAM_UNLOCK(stream); 18 int rc; 19 20 STREAM_XCPT_BEGIN 21 22 STREAM_XCPT_LOCK(stream); 23 rc = _getc_inline(stream); 24 STREAM_XCPT_UNLOCK(stream); 25 26 STREAM_XCPT_END 27 21 28 return rc; 22 29 } 23 30 -
src/emx/src/lib/io/fgets.c
10 10 11 11 char *_STD(fgets)(char *buffer, int n, FILE *stream) 12 12 { 13 STREAM_LOCK(stream); 14 char *psz = fgets_unlocked(buffer, n, stream); 15 STREAM_UNLOCK(stream); 13 char *psz; 14 15 STREAM_XCPT_BEGIN 16 17 STREAM_XCPT_LOCK(stream); 18 psz = fgets_unlocked(buffer, n, stream); 19 STREAM_XCPT_UNLOCK(stream); 20 21 STREAM_XCPT_END 22 16 23 return psz; 17 24 } 18 25 -
src/emx/src/lib/io/flushall.c
12 12 int i, n; 13 13 struct streamvec *sv; 14 14 15 STREAM_XCPT_BEGIN 16 15 17 /* Ignore locked streams to avoid deadlock on process 16 18 termination. */ 17 19 18 20 n = 0; 19 21 for (sv = _streamvec_head; sv != NULL; sv = sv->pNext) 20 22 for (i = 0; i < sv->cFiles; ++i) 21 if ((sv->aFiles[i]._flags & _IOOPEN) && STREAM_ LOCK_NOWAIT (&sv->aFiles[i]))23 if ((sv->aFiles[i]._flags & _IOOPEN) && STREAM_XCPT_LOCK_NOWAIT (&sv->aFiles[i])) 22 24 { 23 25 ++n; 24 26 fflush_unlocked (&sv->aFiles[i]); 25 STREAM_ UNLOCK (&sv->aFiles[i]);27 STREAM_XCPT_UNLOCK (&sv->aFiles[i]); 26 28 } 29 30 STREAM_XCPT_END 31 27 32 return n; 28 33 } -
src/emx/src/lib/io/fprintf.c
14 14 int result; 15 15 void *tb; 16 16 17 STREAM_XCPT_BEGIN 18 17 19 va_start (arg_ptr, format); 18 STREAM_ LOCK (stream);20 STREAM_XCPT_LOCK (stream); 19 21 if (nbuf (stream)) 20 22 _fbuf (stream); 21 23 _tmpbuf (stream, tb); 22 24 result = _output (stream, format, arg_ptr); 23 25 if (_endbuf (stream) != 0) 24 26 result = -1; 25 STREAM_ UNLOCK (stream);27 STREAM_XCPT_UNLOCK (stream); 26 28 va_end (arg_ptr); 29 30 STREAM_XCPT_END 31 27 32 return result; 28 33 } -
src/emx/src/lib/io/fputc.c
16 16 { 17 17 int r; 18 18 19 STREAM_LOCK(stream); 19 STREAM_XCPT_BEGIN 20 21 STREAM_XCPT_LOCK(stream); 20 22 r = _putc_inline(c, stream); 21 STREAM_UNLOCK(stream); 23 STREAM_XCPT_UNLOCK(stream); 24 25 STREAM_XCPT_END 26 22 27 return r; 23 28 } 24 29 … … 31 36 { 32 37 int r; 33 38 34 STREAM_LOCK(stream); 39 STREAM_XCPT_BEGIN 40 41 STREAM_XCPT_LOCK(stream); 35 42 r = _putc_inline(c, stream); 36 STREAM_UNLOCK(stream); 43 STREAM_XCPT_UNLOCK(stream); 44 45 STREAM_XCPT_END 46 37 47 return r; 38 48 } -
src/emx/src/lib/io/fread.c
13 13 14 14 size_t _STD(fread)(void *buffer, size_t size, size_t count, FILE *stream) 15 15 { 16 STREAM_LOCK(stream); 17 size_t cb = fread_unlocked(buffer, size, count, stream); 18 STREAM_UNLOCK(stream); 16 size_t cb; 17 18 STREAM_XCPT_BEGIN 19 20 STREAM_XCPT_LOCK(stream); 21 cb = fread_unlocked(buffer, size, count, stream); 22 STREAM_XCPT_UNLOCK(stream); 23 24 STREAM_XCPT_END 25 19 26 return cb; 20 27 } 21 28 -
src/emx/src/lib/io/fscanf.c
13 13 va_list arg_ptr; 14 14 int result; 15 15 16 STREAM_XCPT_BEGIN 17 16 18 va_start (arg_ptr, format); 17 STREAM_ LOCK (stream);19 STREAM_XCPT_LOCK (stream); 18 20 result = _input (stream, format, arg_ptr); 19 STREAM_ UNLOCK (stream);21 STREAM_XCPT_UNLOCK (stream); 20 22 va_end (arg_ptr); 23 24 STREAM_XCPT_END 25 21 26 return result; 22 27 } -
src/emx/src/lib/io/fseek.c
182 182 { 183 183 int result; 184 184 185 STREAM_LOCK (stream); 185 STREAM_XCPT_BEGIN 186 187 STREAM_XCPT_LOCK (stream); 186 188 result = _fseek_unlocked (stream, offset, origin); 187 STREAM_UNLOCK (stream); 189 STREAM_XCPT_UNLOCK (stream); 190 191 STREAM_XCPT_END 192 188 193 return result; 189 194 } 190 195 -
src/emx/src/lib/io/ftell.c
102 102 { 103 103 off_t off; 104 104 105 STREAM_LOCK (stream); 105 STREAM_XCPT_BEGIN 106 107 STREAM_XCPT_LOCK (stream); 106 108 off = _ftello_unlocked (stream); 107 STREAM_UNLOCK (stream); 109 STREAM_XCPT_UNLOCK (stream); 110 111 STREAM_XCPT_END 112 108 113 return off; 109 114 } 110 115 -
src/emx/src/lib/io/fwide.c
48 48 LIBCLOG_ENTER("pStream=%p iOrientation=%d\n", (void *)pStream, iOrientation); 49 49 int iRet = -1; 50 50 #if 0 /** @todo LIBC07 */ 51 STREAM_LOCK(pStream); 51 STREAM_XCPT_BEGIN 52 STREAM_XCPT_LOCK(pStream); 52 53 if (iOrientation != 0 && pStream->__iOrientation == 0) 53 54 pStream->__iOrientation = iOrientation > 0 ? 1 : -1; 54 55 iRet = pStream->__iOrientation; 55 STREAM_UNLOCK(pStream); 56 STREAM_XCPT_UNLOCK(pStream); 57 STREAM_XCPT_END 56 58 #endif 57 59 LIBCLOG_RETURN_INT(iRet); 58 60 } -
src/emx/src/lib/io/fwrite.c
168 168 { 169 169 size_t r; 170 170 171 STREAM_LOCK (stream); 171 STREAM_XCPT_BEGIN 172 173 STREAM_XCPT_LOCK (stream); 172 174 r = fwrite_unlocked (buffer, size, count, stream); 173 STREAM_UNLOCK (stream); 175 STREAM_XCPT_UNLOCK (stream); 176 177 STREAM_XCPT_END 178 174 179 return r; 175 180 } -
src/emx/src/lib/io/getdelim.c
76 76 *pcchString = 128; 77 77 } 78 78 79 /*80 * Lock the stream and start reading.81 */82 STREAM_LOCK(pStream);83 79 ssize_t rc = 0; 84 80 char *psz = *ppszString; 85 81 char *pszEnd = psz + *pcchString - 1; 82 83 STREAM_XCPT_BEGIN 84 85 /* 86 * Lock the stream and start reading. 87 */ 88 STREAM_XCPT_LOCK(pStream); 86 89 for (;;) 87 90 { 88 91 /** @todo this can be done faster by accessing what's in the buffer directly. … … 117 120 if (ch == chDelim) 118 121 break; 119 122 } 120 STREAM_UNLOCK(pStream); 123 STREAM_XCPT_UNLOCK(pStream); 124 125 STREAM_XCPT_END 121 126 122 127 if (!rc) 123 128 rc = psz - *ppszString; -
src/emx/src/lib/io/gets.c
36 36 37 37 char *_STD(gets)(char *buffer) 38 38 { 39 STREAM_LOCK(stdin); 40 char *psz = gets_unlocked(buffer); 41 STREAM_UNLOCK(stdin); 39 char *psz; 40 41 STREAM_XCPT_BEGIN 42 43 STREAM_XCPT_LOCK(stdin); 44 psz = gets_unlocked(buffer); 45 STREAM_XCPT_UNLOCK(stdin); 46 47 STREAM_XCPT_END 48 42 49 return psz; 43 50 } 44 51 -
src/emx/src/lib/io/printf.c
14 14 int result; 15 15 void *tb; 16 16 17 STREAM_XCPT_BEGIN 18 17 19 va_start (arg_ptr, format); 18 STREAM_ LOCK (stdout);20 STREAM_XCPT_LOCK (stdout); 19 21 if (nbuf (stdout)) 20 22 _fbuf (stdout); 21 23 _tmpbuf (stdout, tb); 22 24 result = _output (stdout, format, arg_ptr); 23 25 if (_endbuf (stdout) != 0) 24 26 result = -1; 25 STREAM_ UNLOCK (stdout);27 STREAM_XCPT_UNLOCK (stdout); 26 28 va_end (arg_ptr); 29 30 STREAM_XCPT_END 31 27 32 return result; 28 33 } -
src/emx/src/lib/io/puts.c
11 11 12 12 int _STD(puts) (const char *string) 13 13 { 14 STREAM_LOCK(stdout); 15 int rc = puts_unlocked(string); 16 STREAM_UNLOCK(stdout); 14 int rc; 15 16 STREAM_XCPT_BEGIN 17 18 STREAM_XCPT_LOCK(stdout); 19 rc = puts_unlocked(string); 20 STREAM_XCPT_UNLOCK(stdout); 21 22 STREAM_XCPT_END 23 17 24 return rc; 18 25 } 19 26 -
src/emx/src/lib/io/rewind.c
9 9 10 10 void _STD(rewind) (FILE *stream) 11 11 { 12 STREAM_LOCK (stream); 12 STREAM_XCPT_BEGIN 13 STREAM_XCPT_LOCK (stream); 13 14 fflush_unlocked (stream); 14 15 _fseek_unlocked (stream, 0, SEEK_SET); 15 16 stream->_flags &= ~_IOERR; 16 STREAM_UNLOCK (stream); 17 STREAM_XCPT_UNLOCK (stream); 18 STREAM_XCPT_END 17 19 } -
src/emx/src/lib/io/scanf.c
13 13 va_list arg_ptr; 14 14 int result; 15 15 16 STREAM_XCPT_BEGIN 17 16 18 va_start (arg_ptr, format); 17 STREAM_ LOCK (stdin);19 STREAM_XCPT_LOCK (stdin); 18 20 result = _input (stdin, format, arg_ptr); 19 STREAM_ UNLOCK (stdin);21 STREAM_XCPT_UNLOCK (stdin); 20 22 va_end (arg_ptr); 23 24 STREAM_XCPT_END 25 21 26 return result; 22 27 } -
src/emx/src/lib/io/setvbuf.c
13 13 || (mode != _IONBF && mode != _IOFBF && mode != _IOLBF)) 14 14 return EOF; 15 15 16 STREAM_LOCK (stream); 16 STREAM_XCPT_BEGIN 17 18 STREAM_XCPT_LOCK (stream); 17 19 fflush_unlocked (stream); 18 20 if ((stream->_flags & _IOBUFMASK) == _IOBUFLIB) 19 21 free (stream->_buffer); … … 48 50 buffer = malloc (size); 49 51 if (buffer == NULL) 50 52 { 51 STREAM_ UNLOCK(stream);53 STREAM_XCPT_UNLOCK_END(stream); 52 54 return EOF; 53 55 } 54 56 stream->_buf_size = size; … … 58 60 stream->_ptr = stream->_buffer; 59 61 stream->_rcount = 0; 60 62 stream->_wcount = 0; 61 STREAM_UNLOCK (stream); 63 STREAM_XCPT_UNLOCK (stream); 64 65 STREAM_XCPT_END 66 62 67 return 0; 63 68 } -
src/emx/src/lib/io/ungetc.c
153 153 { 154 154 int result; 155 155 156 STREAM_LOCK (stream); 156 STREAM_XCPT_BEGIN 157 158 STREAM_XCPT_LOCK (stream); 157 159 result = _ungetc_nolock (c, stream); 158 STREAM_UNLOCK (stream); 160 STREAM_XCPT_UNLOCK (stream); 161 162 STREAM_XCPT_END 163 159 164 return result; 160 165 } -
src/emx/src/lib/io/vfprintf.c
12 12 int result; 13 13 void *tb; 14 14 15 STREAM_LOCK (stream); 15 STREAM_XCPT_BEGIN 16 17 STREAM_XCPT_LOCK (stream); 16 18 if (nbuf (stream)) 17 19 _fbuf (stream); 18 20 _tmpbuf (stream, tb); 19 21 result = _output (stream, format, arg_ptr); 20 22 if (_endbuf (stream) != 0) 21 23 result = -1; 22 STREAM_UNLOCK (stream); 24 STREAM_XCPT_UNLOCK (stream); 25 26 STREAM_XCPT_END 27 23 28 return result; 24 29 } -
src/emx/src/lib/io/vfscanf.c
12 12 { 13 13 int r; 14 14 15 STREAM_LOCK (stream); 15 STREAM_XCPT_BEGIN 16 17 STREAM_XCPT_LOCK (stream); 16 18 r = _input (stream, format, arg_ptr); 17 STREAM_UNLOCK (stream); 19 STREAM_XCPT_UNLOCK (stream); 20 21 STREAM_XCPT_END 22 18 23 return r; 19 24 } -
src/emx/src/lib/io/vprintf.c
12 12 int result; 13 13 void *tb; 14 14 15 STREAM_LOCK (stdout); 15 STREAM_XCPT_BEGIN 16 17 STREAM_XCPT_LOCK (stdout); 16 18 if (nbuf (stdout)) 17 19 _fbuf (stdout); 18 20 _tmpbuf (stdout, tb); 19 21 result = _output (stdout, format, arg_ptr); 20 22 if (_endbuf (stdout) != 0) 21 23 result = -1; 22 STREAM_UNLOCK (stdout); 24 STREAM_XCPT_UNLOCK (stdout); 25 26 STREAM_XCPT_END 27 23 28 return result; 24 29 } -
src/emx/src/lib/io/vscanf.c
12 12 { 13 13 int r; 14 14 15 STREAM_LOCK (stdin); 15 STREAM_XCPT_BEGIN 16 17 STREAM_XCPT_LOCK (stdin); 16 18 r = _input (stdin, format, arg_ptr); 17 STREAM_UNLOCK (stdin); 19 STREAM_XCPT_UNLOCK (stdin); 20 21 STREAM_XCPT_END 22 18 23 return r; 19 24 }