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