11 * Attempt to join with an uninitialized thread ID. On most

12 * implementations, this will return an ESRCH error code. If

13 * the local (and uninitialized) pthread_t happens to be a valid

14 * thread ID, it is almost certainly that of the initial thread,

15 * which is running main(). In that case, your Pthreads

16 * implementation may either return EDEADLK (self-deadlock),

17 * or it may hang. If it hangs, quit and try again. */

18 */

19 status = pthread_join (thread, NULL);

20 if (status != 0)

21  fprintf (stderr, "error %d: %s\n", status, strerror (status));

22 return status;

23 }

Note that there is no equivalent to the perror function to format and print an error value returned by the Pthreads interfaces. Instead, use strerror to get a string description of the error number, and print the string to the file stream stderr.

To avoid cluttering each function call in the example programs with a block of code to report each error and call abort, I have built two error macros—err_abort detects a standard Pthreads error, and errno_abort is used when a value of -1 means that errno contains an error code. The following header file, called errors.h, shows these macros. The errors.h header file also includes several system header files, which would otherwise be required by most of the example programs—this helps to reduce the size of the examples.

■ errors.h

1 #ifndef _errors_h

2 #define _errors_h

3

4 #include

5 #include

6 #include

7 #include

8 #include

9

10 /*

11 * Define a macro that can be used for diagnostic output from

12 * examples. When compiled -DDEBUG, it results in calling printf

13 * with the specified argument list. When DEBUG is not defined, it

14 * expands to nothing.

15 */

16 #ifdef DEBUG

17 # define DPRINTF(arg) printf arg

18 #else

19 # define DPRINTF(arg)

20 #endif

21

22 /*

23 * NOTE: the "do {" ... "} while (0);" bracketing around the macros

24 * allows the err_abort and errno_abort macros to be used as if they

25 * were function calls, even in contexts where a trailing ";" would

26 * generate a null statement. For example,

27 *

28 * if (status != 0)

29 * err_abort (status, "message");

30 * else

31 * return status;

32 *

33 * will not compile if err_abort is a macro ending with "}", because

34 * C does not expect a ";" to follow the "}". Because C does expect

35 * a ";" following the ")" in the do...while construct, err_abort and

36 * errno_abort can be used as if they were function calls.

37 */

38 #define err_abort(code,text) do { \

39  fprintf (stderr, "%s at \"%s\":%d: %s\n", \

40  text, _FILE_, _LINE_, strerror (code)); \

41  abort (); \

42 } while (0)

43 #define errno_abort(text) do { \

44  fprintf (stderr, "%s at \"%s\":%d: %s\n", \

45  text, _FILE_, _LINE_, strerror (errno)); \

46  abort ( ); \

47 } while (0)

48

49 #endif

Перейти на страницу:

Похожие книги