View Issue Details

IDProjectCategoryView StatusLast Update
00008741003.1(2013)/Issue7+TC1System Interfacespublic2019-06-10 08:54
Reportergeoffclare Assigned To 
PrioritynormalSeverityCommentTypeError
Status ClosedResolutionAccepted As Marked 
NameGeoff Clare
OrganizationThe Open Group
User Reference
Sectionpthread_once()
Page Number1685
Line Number54518
Interp Status---
Final Accepted Text0000874:0002417
Summary0000874: pthread_once() rationale makes bogus claims
DescriptionThe following paragraph in the pthread_once() rationale makes bogus claims about the need for pthread_once():
For dynamic library initialization in a multi-threaded process, a simple initialization flag is not sufficient; the flag needs to be protected against modification by multiple threads simultaneously calling into the library. Protecting the flag requires the use of a mutex; however, mutexes have to be initialized before they are used. Ensuring that the mutex is only initialized once requires a recursive solution to this problem.


Ensuring that a mutex is only initialised once does not require a recursive solution. All it requires is:
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;


Also, "protecting the flag requires the use of a mutex" is not true, as there are other ways that the flag could be protected.

In addition, there is a bug in the example code: the initialize_random() function should have return type void, not int.
Desired ActionOn page 1684 line 54506 section pthread_once()
and page 1685 line 54528 section pthread_once()

In the RATIONALE section, change from:
extern int initialize_random();

to:
extern void initialize_random(void);


On page 1685 line 54518 section pthread_once()

In the RATIONALE section, change from:

For dynamic library initialization in a multi-threaded process, a simple initialization flag is not sufficient; the flag needs to be protected against modification by multiple threads simultaneously calling into the library. Protecting the flag requires the use of a mutex; however, mutexes have to be initialized before they are used. Ensuring that the mutex is only initialized once requires a recursive solution to this problem.

The use of pthread_once() not only supplies an implementation-guaranteed means of dynamic initialization, it provides an aid to the reliable construction of multi-threaded and realtime systems. The preceding example then becomes:

to:

For dynamic library initialization in a multi-threaded process, if an initialization flag is used the flag needs to be protected against modification by multiple threads simultaneously calling into the library. This can be done by using a mutex (initialized by assigning PTHREAD_MUTEX_INITIALIZER). However, the need for a flag can be avoided altogether by using pthread_once() as follows:
Tagstc2-2008

Activities

dalias

2014-09-06 13:14

reporter   bugnote:0002375

While I agree the current text is imprecise, I'm not sure it's a good idea to downplay the importance of pthread_once. Using a mutex for dynamic initialization is highly inappropriate because each lock/unlock operation synchronizes with every other one, whereas (at least morally; this still needs to be addressed formally as part of the C11 alignment project) pthread_once calls synchronize only with completion of the first call.

My personal experience has been that there is still a huge abundance of dynamic library code performing non-thread-safe initialization (e.g. requiring the caller to call a library-init function, which does not work if there are potentially multiple first-callers in a multi-threaded application). So if anything, I'd like to see the Application Usage and/or Rationale for pthread_once doing more to encourage proper usage, rather than just casually offering it as one alternative.

rhansen

2014-10-09 16:20

manager   bugnote:0002417

On page 1684 line 54506 section pthread_once()
and page 1685 line 54528 section pthread_once()
in the RATIONALE section, change from:
extern int initialize_random();

to:
extern void initialize_random(void);

On page 1685 line 54518 section pthread_once() in the RATIONALE section, change from:
For dynamic library initialization in a multi-threaded process, a simple initialization flag is not sufficient; the flag needs to be protected against modification by multiple threads simultaneously calling into the library. Protecting the flag requires the use of a mutex; however, mutexes have to be initialized before they are used. Ensuring that the mutex is only initialized once requires a recursive solution to this problem.

The use of pthread_once() not only supplies an implementation-guaranteed means of dynamic initialization, it provides an aid to the reliable construction of multi-threaded and realtime systems. The preceding example then becomes:

to:
For dynamic library initialization in a multi-threaded process, if an initialization flag is used the flag needs to be protected against modification by multiple threads simultaneously calling into the library. This can be done by using a mutex (initialized by assigning PTHREAD_MUTEX_INITIALIZER). However, the better solution is to use pthread_once(), which is designed for exactly this purpose, as follows:

Issue History

Date Modified Username Field Change
2014-09-05 10:31 geoffclare New Issue
2014-09-05 10:31 geoffclare Name => Geoff Clare
2014-09-05 10:31 geoffclare Organization => The Open Group
2014-09-05 10:31 geoffclare Section => pthread_once()
2014-09-05 10:31 geoffclare Page Number => 1685
2014-09-05 10:31 geoffclare Line Number => 54518
2014-09-05 10:31 geoffclare Interp Status => ---
2014-09-06 13:14 dalias Note Added: 0002375
2014-10-09 16:20 rhansen Note Added: 0002417
2014-10-09 16:21 rhansen Final Accepted Text => 0000874:0002417
2014-10-09 16:21 rhansen Status New => Resolved
2014-10-09 16:21 rhansen Resolution Open => Accepted As Marked
2014-10-09 16:22 rhansen Tag Attached: tc2-2008
2019-06-10 08:54 agadmin Status Resolved => Closed