Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is _GNU_SOURCE macro required for pthread_mutexattr_settype() while it is in POSIX/IEEE standard?

I have written a multithread server program in C, which echoes back all the data that a client sends.

Initially, I used poll() function in my program to detect POLLRDHUP event, for that I defined _GNU_SOURCE macro (This event is defined here).

Later I updated my code & removed poll() function, however I forgot to remove _GNU_SOURCE macro.

Now my code is finally complete (and a little long to post, more than 250 lines). Before removing macro I was compiling my program using:

gcc multi_thread_socket_v4.c -Wall -Werror -g -lpthread -o multi_thread_socket

and it worked fine: No errors, no warnings

After I removed the macro definition, and compiled using same command-line, the output of gcc was:

multi_thread_socket_v4.c: In function ‘main’:
multi_thread_socket_v4.c:194: warning: implicit declaration of function ‘pthread_mutexattr_settype’
multi_thread_socket_v4.c:194: error: ‘PTHREAD_MUTEX_ERRORCHECK’ undeclared (first use in this function)
multi_thread_socket_v4.c:194: error: (Each undeclared identifier is reported only once
multi_thread_socket_v4.c:194: error: for each function it appears in.)

I have included all the required libraries as it worked fine initially.

I peeked into pthread.h at /usr/include/pthread.h and found out this:

/* Mutex types.  */
enum
{
  PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_ADAPTIVE_NP
#ifdef __USE_UNIX98
  ,
  PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
  PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
  PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
  PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
#endif
#ifdef __USE_GNU
  /* For compatibility.  */
  , PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
#endif
};

and this:

#ifdef __USE_UNIX98
/* Return in *KIND the mutex kind attribute in *ATTR.  */
extern int pthread_mutexattr_gettype (__const pthread_mutexattr_t *__restrict
                      __attr, int *__restrict __kind)
     __THROW __nonnull ((1, 2));

/* Set the mutex kind attribute in *ATTR to KIND (either PTHREAD_MUTEX_NORMAL,
   PTHREAD_MUTEX_RECURSIVE, PTHREAD_MUTEX_ERRORCHECK, or
   PTHREAD_MUTEX_DEFAULT).  */
extern int pthread_mutexattr_settype (pthread_mutexattr_t *__attr, int __kind)
     __THROW __nonnull ((1));

I checked out here to check if __USE_UNIX98 is a feature test macro, but it was not there.

So please help me understanding the reasons for the error, because the function & the macro where gcc shows error are defined in POSIX standard. I do not know what more info regarding my problem will be required so please tell me, I will update my question.

like image 692
Don't You Worry Child Avatar asked Aug 22 '13 08:08

Don't You Worry Child


2 Answers

You should use

#define _POSIX_C_SOURCE 200112L

if you want to use POSIX features such as pthread_mutexattr_settype ... see http://pubs.opengroup.org/onlinepubs/007904975/functions/xsh_chap02_02.html

Another possibility is

#define _XOPEN_SOURCE 700

See http://man7.org/linux/man-pages/man7/feature_test_macros.7.html and http://pubs.opengroup.org/onlinepubs/9699919799/

Setting _GNU_SOURCE includes POSIX and lots of other definitions.

P.S. I would expect that including <pthread.h> includes <features.h>, which by default defines _POSIX_C_SOURCE as 200112L, but it's possible that you have defined something that overrides that ... see /usr/include/features.h on your system for details of the symbols and their usage.

like image 56
Jim Balter Avatar answered Nov 05 '22 07:11

Jim Balter


It doesn't, your problem likely lies elsewhere.

I just compiled a trivial program with the following content:

#include <pthread.h>

int main(int argc, char **argv)
{
    pthread_mutexattr_t attr;

    pthread_mutexattr_init(&attr);
    pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_ERRORCHECK);

    return 0;
}

This compiles perfectly with gcc -pthread -Wall -Werror a.c.

It's possible that another part of your program causes this, by eg. doing something silly like defining _PTHREAD_H, or some other minor sabotage.

You might want to try to get a minimal test case by using a tool like delta or creduce, which will probably make the problem evident.

like image 39
Hasturkun Avatar answered Nov 05 '22 06:11

Hasturkun