JTC1/SC22
N2594
Date: Thu, 9 Oct 1997 13:27:01 -0400 (EDT)
From: "william c. rinehuls" <[email protected]>
To: [email protected]
Subject: SC22 N2594 - Record of Responses for Defect Reports re Amendment 2 to 9945-1 - POSIX C Binding
_____________ beginning of title page ________________________________
ISO/IEC JTC 1/SC22
Programming languages, their environments and system software interfaces
Secretariat: U.S.A. (ANSI)
ISO/IEC JTC 1/SC22
N2594
TITLE:
WG15 Record of Responses for Defect Reports 1 through 32 for Amendment 2
to ISO/IEC 9945-1:1990 - Information technology - Portable Operating
System Interface (POSIX) - POSIX C Binding And Letter Ballot
DATE ASSIGNED:
1997-10-07
SOURCE:
Secretariat, ISO/IEC JTC 1/SC22
BACKWARD POINTER:
N/A
DOCUMENT TYPE:
Record of Responses for Defect Reports
PROJECT NUMBER
JTC 1.22.21.04.01
STATUS:
In accordance with SC22 N1236, non-responses to the letter ballot will be
considered as agreement with the proposed record of responses.
Note that Amendment 2 was incorporated into ISO/IEC 9945-1 when it was
revised in 1996.
ACTION IDENTIFIER:
ACT
DUE DATE:
1998-02-09
DISTRIBUTION:
Text
CROSS REFERENCE:
N/A
DISTRIBUTION FORM:
Open
Address reply to:
ISO/IEC JTC 1/SC22 Secretariat
William C. Rinehuls
8457 Rushing Creek Court
Springfield, VA 22153 USA
Telephone: +1 (703) 912-9680
Fax: +1 (703) 912-2973
email: [email protected]
____________________end of title page; beginning of letter ballot _____
----------------------------------------------------------------------
Attachment to
JTC 1/SC22 N2594
Circulation Date: 10-24-97
LETTER BALLOT
FROM THE MEMBER BODY OF ___________________________________________
On WG15 Record of Responses for Defect Reports 01 through 32 for Amendment
2 to ISO/IEC 9945-1:1990 - Information technology - Portable Operating
System Interface (POSIX) - POSIX C Binding
This letter ballot is to be returned by each "P" Member Body to the
Secretariat of JTC 1/SC22 by FEBRUARY 9, 1998.
-------------------------------------------------------------------------
_____ We agree with the Record of Responses
or
_____ We agree with the Record of Responses with the attached comments
or
_____ We do not agree with the Record of Responses for the technical
reasons attached to this ballot.
or
_____ We abstain from voting.
("P" MEMBER BODIES HAVE AN OBLIGATION TO VOTE.)
* CHECK WHICHEVER APPLIES.
Name (please print) _______________________
Signature (if mailed) _____________________ Date: _________
-------------------------------------------------------------------------
______ end of letter ballot; beginning of document _____________________
WG15 Record of Responses for Defect Reports 1 through 32
for
Amendment 2 to ISO/IEC 9945-1:1990 - Information technology - Portable
Operating System Interface (POSIX), POSIX C Binding
Below find 24 Records of Response for interpretations/defects as reported
by the U.S. to WG15. They are numbered with the Standard (IS 9945-1Amd2),
followed by a tracking number used in the U.S.
This is proposed to SC22 as a Record of Responses for approval by SC22 for
the defects/interpretations indicated in the text.
The specific Defect Reports included are 1 through 4, 6 through 16, 18
through 22, 24, 27, 28 and 32. The missing numbers reference reports that
did not require a record of response (withdrawn, technical corregenda), or
which have not yet resulting in an accepted response.
ISO/IEC 9945-1-amd2 Interpretations Log
------------------------------------------------------------------------
9945-1-amd2-01
Topic: Get User Name Relevant Sections: 4.2.4, 4.7.2
9945-1-amd2-02
Topic: pthread_key_delete Relevant Sections: 2.8.4, 17.1.1.4,
17.1.3
9945-1-amd2-03
Topic: Miscellaneous Relevant Sections: Many
9945-1-amd2-04
Topic: pthread_atfork - Headers and Functions Relevant Sections:
3.1.3.1 lines 79-81 , 2.7.3
9945-1-amd2-06
Topic: 6.7.1.1 Relevant Sections: _POSIX_PRIORITIZED_IO
9945-1-amd2-07
Topic: PTHREAD_INHERIT_SCHED Relevant Sections: ??
9945-1-amd2-08
Topic: pthread_key_create() Relevant Sections: 17.1.1.2
9945-1-amd2-09
Topic: pthread_atfork() Relevant Sections: 3.1.3.1
9945-1-amd2-10
Topic: cancellation points Relevant Sections: 18.1.2
9945-1-amd2-11
Topic: sigpending() Relevant Sections: 3.3.6.2
9945-1-amd2-12
Topic: thread specific data Relevant Sections: 3.1.3.2
9945-1-amd2-13
Topic: sigevent structure Relevant Sections: 6.7.1.1 (POSIX
9945-1-amd1-93)
9945-1-amd2-14
Topic: stacksize Relevant Sections: 16.1.1.2
9945-1-amd2-15
Topic: default value for attribute Relevant Sections: 13.5.1.2
9945-1-amd2-16
Topic: sigpending Relevant Sections: 3.3.6.2
9945-1-amd2-18
Topic: stackaddr attribute Relevant Sections: 16.1.1.2
9945-1-amd2-19
Topic: sched_setparam Relevant Sections: 13.3.3.2
9945-1-amd2-20
Topic: protocol attribute etc Relevant Sections: 13.6.1.2
9945-1-amd2-21
Topic: timers and SIGEV_THREAD Relevant Sections: 14.2.2.2
(9945-1-amd1)
9945-1-amd2-22
Topic: pthread_setspecific Relevant Sections: 17.1.2.2
9945-1-amd2-24
Topic: schedpolicy etc Relevant Sections: 13.5.1.2
9945-1-amd2-27
Topic: pthread_mutexattr_init Errors Relevant Sections: 11.3.1.4
9945-1-amd2-28
Topic: Waiting on a Condition Errors Relevant Sections: 11.4.4.4
9945-1-amd2-32
Topic: Thread-Specific Data Key Creation Description Relevant
Sections: 17.1.1.2
------------------------------------------------------------------------
WG15 Defect Report Ref: 9945-1-amd2-01
Topic: Get User Name
9945-1-amd2-95 #1
Defect Report Number: XXXX
Topic: Get User Name
Relevant Sections: 4.2.4, 4.7.2
Defect Report:
-----------------------
I am referring to sections 4.2.4 (Get User Name) and 4.7.2 (Determine
Terminal Device Name). POSIX.1c is ambiguous when getlogin_r() and
ttyname_r() cannot find the login or tty name, requiring that an error
code is to be returned but not identifying a specific error code.
Since the standard fails to specify a return code, applications cannot
expect to portably handle this condition.
Is this an oversight in the specification? I suggest that ESRCH should
be the error returned these functions cannot find a name.
Interpretation response
------------------------
The standard does not speak to this issue and as such no conformance
distinction can be made between alternative implementations
based on this.
The standard is silent on what err shall be returned and the
interpretations
committee belives that the silence is intentional. Strictly conforming
implementations are not constrainted in what they may return and
applications
shall be ready to deal with varying behaviors.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-02
Topic: pthread_key_delete
9945-1-amd2-95 #2
Defect Report Number: XXXX
Topic: pthread_key_delete
Relevant Sections: 2.8.4, 17.1.1.4, 17.1.3
Defect Report:
-----------------------
This is a request for interpretation on an issue in the forthcoming
POSIX 9945-1-amd2, presumably 1996. Right now all I have to work from
are the draft 8, 9, and 10 documents, but draft 10 was approved as the
final specification.
My question involves sections 2.8.4, 17.1.1.4, and 17.1.3
Briefly, may/must pthread_key_delete make the key value available
for re-use?
Section 2.8.4 defines PTHREAD_KEYS_MAX as being the number of data
keys that can created per process.
17.1.1.4 says that pthread_key_create shall return EAGAIN if "the
system-imposed limit on the total number of keys per process
{PTHREAD_KEYS_MAX} has been exceeded."
17.1.3.2 the rationale for pthread_key_delete, says "A thread-specific
data key deletion function has been included in order to allow the
resources associated with an unused thread-specific data key to be
freed."
Consider the following example. Assume that this application does
nothing else with any thread-specific data.
pthread_key_t keys[PTHREAD_KEYS_MAX], key_A, key_B;
int i, status_A, status_B;
struct foobar data[PTHREAD_KEYS_MAX];
for (i = 0; i < PTHREAD_KEYS_MAX; i++)
{
/* these calls all succeed */
(void) pthread_key_create (&(keys[i]), NULL);
pthread_setspecific (keys[i], (void *) &(data[i]));
}
pthread_key_delete(keys[5]); /* this should succeed */
status_A = pthread_key_create (&key_A, NULL); /* Unclear about this
*/
pthread_setspecific (keys[6], (void *) NULL); /* this should succeed
*/
pthread_key_delete(keys[6]); /* this should succeed */
status_B = pthread_key_create (&key_B, NULL); /* Unclear about this
*/
Questions:
1) May status_A be 0? (I recommend "yes")
1.1) If so, may key_A equal keys[5]? (I recommend "yes")
2) Must status_A be 0? (I recommend "no")
3) May status_A be EAGAIN? (I recommend "yes")
4) Must status_A be EAGAIN? (I recommend "no")
5) May status_B be 0? (I recommend "yes")
5.1) If so, may key_B equal keys[6]? (I recommend "yes")
6) Must status_B be 0? (I recommend "no")
7) May status_A be EAGAIN? (I recommend "yes")
8) Must status_A be EAGAIN? (I recommend "no")
I expect that the answers to questions 1-4 will be identical to the
answers to 5-8, but I wanted to point out the distinction of having a
non-NULL thread-specific data value at the time of the
pthread_key_delete
call.
The answers I have recommended above coincide with my reading of
the normative text of the standard, but the wording in the 17.1.3.2
rationale for pthread_key_delete leaves me uneasy.
While I have your attention, I'll add another question that is somewhat
redundant with the above.
9) In 2.8.4, should the definition for PTHREAD_KEYS_MAX, which reads
"Maximum number of data keys that can be created per process", be
interpreted to not include in the count those data keys that have
been deleted? If so, I would suggest changing the definition to
"Maximum number of data keys that can exist per process".
Interpretation response
------------------------
The standard states that once the system defined limit:
PTHREADS_KEYS_MAX keys have been created, the call shall return the
indicated error and conforming implementations must conform to this.
However, concerns have been raised about this behavior which are
being forwarded to the sponsor. In the view of the
interpretations committee, this is not what the balloting group
intended. The provision of a Delete function and the rationale for this
function make the intent very clear that keys should be reusable with a
limit on the number of "simultaneous" keys. The wording in the definition
should possibly have been similar to POSIX_OPEN_MAX or POSIX_CHILD_MAX.
This matter is being refered to the sponsor for consideration as a
technical correction. Additionally, the interpretation committee noted
that PTHREADS_THREADS_MAX may have a similar problem and have refered this
to the sponsor as well.
Specific answers:
1. -> No
2. -> No
3. -> Yes, must be EAGIN
4. -> Yes,
5. -> No
6. -> No
7./8. same as 3/4"
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-03
Topic: Miscellaneous
9945-1-amd2-95 #3
Topic: Miscellaneous
Relevant Sections: Many
Defect Report:
-----------------------
1) Section 16.1.1.2, page 141 D10, lines 79-83
A default value for the stackaddr attribute is not specified. The
bahvior is specified if an application wants to specify their own stack.
It does not specify what to do if they want to implementation to create a
stack for them.
What is the default value of this attribute? NULL to signify the user
wants the implementation to allocate stacks?
2) Section 16.1.1.2, page 141 D10, lines 74-78
A default value of the stacksize attribute is not specified. The
behavior is specified if an application wants to specify their own stack
size. It does not specify the value of stacksize if the user wants the
implementation to use a default stacksize.
What is the correct stacksize to return as a default value when the user
has not specified a stacksize? Some implementations specify a default
value of 0 for a default stack. Other implementations specify a default
value of PTHREAD_STACK_MIN. This confusion can lead to source code
portablity problems.
3) Section 13.5.1.2, page 121 D10, lines 316-332
A default value for the inheritsched attribute is not specified. The
default behavior needs to be specified for portable applications or
it could result in differing behavior across platforms.
What is the default value for inheritsched?
4) Section 13.5.1.2, page 122 D10, lines 333-342
A default value for the schedpolicy attribute is not specified.
What is the default value for this attribute?
5) Section 13.5.1.2, page 122 D10, lines 353-357
A default value for the schedparam attribute is not specified.
What is the default value for this attribute? Implementations are
already providing different values (drastically) which will effect
portability. Some implementations consider the default value
to be NULL, others return an actual value for this attribute as the
default value. This case is not merely different default values,
but actual differences in what this attribute represents. This
impacts portability.
What is the default value/behavior of this attribute?
6) Section 17.1.2.2, page 166 D10, lines 192-195
This paragraph states that calling pthread_setspecific() from within a
destructor function may result in lost storage or infinite loops.
This can be a real problem. POSIX.1c has just stated that it is
impossible to use thread-specific data in an application. A portable and
correctly behaving application cannot rely on calling
pthread_setspecific() from within a destructor function.
What makes thread-specific data impossible to use is the fact that in
pthread_key_create() it is stated that when a thread terminates, any
non-NULL TSD values which have destructors will have the destructor
called for them. The problem here is that the destructor function is
called in a loop (potentially forever - so a portable application has to
assume forever) until the key value is NULL. However, according to
pthread_setspecifc() a portable and correctly behaving application has no
way possible to change the key value to a NULL value.
Portable application have to rely on "worst case" guaranteed behavior.
According to the definitions of pthread_setspecific() and
pthread_key_create() an application cannot reliably make use of
thread-specific data with destructor functions or its thread will end up
in an infinite loop.
Could you please clarify the intended behavior of these functions?
Obviously there must be something missing here or this looping behavior
for destructor functions would not have been added since an application
must assume it results in an infinite loop.
7) Section 13.3.1.2, page 114 D10, lines 30-36
Section 13.3.3.2, page 114 D10, lines 42-48
According to the new rules for scheduling, the sched_setparam() and
sched_setscheduler() are not useless in the presence of multithreaded
applications. The only effect these functions have is on the child
process (from fork()) of the target process. An implementation may cause
something to happen to the process scope threads, but thats all.
This provides a huge hole for system administrators. These functions have
a process d parameter. This means they were intended so that a process
could control the policy and priority of another process. If that wasn't
the case, there wouldn't have been a pid as a parameter. Up until now
a system administrator could control a process if it was getting too much
or too little time on the system. Runaway processes with high priority
could be habndled.
With the new behavior, there is no way a sysadmin (or any process) can
control the behavior of a multithreaded process. If some event happens
requiring a change in the policy/priority of the MT process, only the
process itself can do it.
The worst part is that if one thread in the process goes out of control
while high prio SCHED_FIFO, no one can control it. A sysadmin cannot
do anything to lower that thread's priority (thread IDs are not
guaranteed to be known outside of the system).
Is this the actual intended behavior?????
8) Section 13.6.1.2, page 128-129 D10, lines 581-587
What is the default value of the protocol attribute?
9) Section 13.6.1.2, page 128-129 D10, lines 578-580, 595-606
PTHREAD_PRIO_PROTECT
This states that a) the priority of the locking thread shall raise its
priority to the mutex prioceiling and b) that prioceiling must be a valid
priority for SCHED_FIFO.
What happens if the locking thread is not SCHED_FIFO? Chances are pretty
good that the prioceiling value is not a valid priority for the
scheduling policy of the thread. Even if the thread is SCHED_RR the value
may not be valid. Do these functons imply that you must also change the
scheduling policy of the locking thread to SCHED_FIFO? If so, what happens
if the system defines SCHED_FIFO to have lower priorities than say
SCHED_RR and the thread is under SCHED_RR?
10) Section 13.6.1.2, page 128-129 D10, lines 590-594
PTHREAD_PRIO_INHERIT
This states that the blocking thread shall raise the priority of the
thread owning the mutex to equal that of the blocking thread.
Only the priority is being changed here. What happens if the threads are
in different scheduling policies? The new priority may not be valid in
that scheduling policy. Is it assumed that these functions also change the
policy of the thread if they are different?
11) Section 3.1.3.2, page 27 D10, lines 84-94
This function allows an application to essentially install cancellation
type handlers to guarantee that the proper state is maintained in the
child process after a fork.
What is supposed to happen with allocated thread-secific data in the child
process? These functions are, in effect, executed by the thread calling
fork. If the other threads have allocated a lot of thread-specific data,
there is no way for the process to release that memory. The child has
immediately inherited a memory leak when using TSD. Is this intended?
12) Section 3.3.6.2, page 39 D10, lines 492-494
This section states that sigpending() returns the signals pending on
"either" the process or the thread. The way stated, an implementation is
allowed to return process pending signals or thread pending signals.
An application cannot portably use and rely on what this function does
because of "either".
What the actual intent to say something more like "returns the union of
the signals pending on the process and the calling thread"?
13) Section --> None in 9945-1-amd2 D10, corresponding section in
9945-1-amd1 is
Section 14.2.2.2
The behavior for timer_create() specifies what happens when a sigevent
structure of type SIGEV_NONE or type SIGEV_SIGNAL is passed to the
function.
POSIX.1c does not specify what the behavior of this function is if the
sigevent structure is for SIGEV_THREAD. The most complicated part is
when sigevent specifies SIGEV_THREAD but the timer is a reloading timer
so that it continually expires.
What is supposed to happen with timers and SIGEV_THREAD? A thread is to
be created when the timer expires? What happens with reloading timers
which continually expire? Does only one thread get created and from then
on an overrun count is incremented? Since these threads are detached, you
have no way of knowing this thread terminates in order to stop
incrememnting the count and create a new thread on the next timer
expiration.
Interpretation response
------------------------
1. Stack address:
The standard is clear that the default value of the stackaddr
attribute is "unspecified". A conforming system is free to choose any
value for this field and a conforming application must correctly
handle any value. If the attribute is supported, the application can
specify the placement of the stack by using an attribute object for
thread creation and the function pthread_attr_setsetstacksize. The
interpretations committee believes that this was the intent of the
working and balloting groups. Due to the complexities of O/S and
compiler interactions, the expectation was that the thread
implementation will wish to reserve to itself the ability to
determine the placement and size of the stack. The rationale for
adding the functions to set the fields was derived from the needs of
real-time systems and embedded environments where the management of
memory is often handled by the application writer. An application
writer wishing to force a particular stack address will need to be
vary cautious since different systems, processors, O/Ss, and
compilers will varying in the amount of memory required for the stack
of an application. This issue is analogous to the stack creation in
the exec functions, where there are no particular requirements on the
location or size of the stack in the new process image.
2. Stack size:
The standard is clear that the default value of the stacksize
attribute is "unspecified". A conforming system is free to choose any
value for this field and a conforming application must correctly
handle any value. If the attribute is supported, the application can
specify the value of the stack size by using an attribute object for
thread creation and the function pthread_attr_setsetstacksize. The
interpretations committee believes that this was the intent of the
working and balloting groups. Due to the complexities of O/S and
compiler interactions, the expectation was that the thread
implementation will wish to reserve to itself the ability to
determine the placement and size of the stack. The rationale for
adding the functions to set the fields was derived from the needs of
real-time systems and embedded environments where the management of
memory is often handled by the application writer. An application
writer wishing to force a particular stack size will need to be vary
cautious since different systems, processors, O/Ss, and compilers
will varying in the amount of memory required for the stack of an
application. This issue is analogous to the stack creation in the
exec functions, where there are no particular requirements on the
location or size of the stack in the new process image.
3. Inheritsched
The standard is clear that the default value of the inheritsched
attribute is "unspecified". A conforming system is free to choose any
value for this field and a conforming application must correctly
handle any value. The application can specify the value of
inheritsched by setting it in the attribute object using the function
pthread_attr_setinheritsched. The interpretations committee believes
that this was the intent of the working and balloting groups. Due to
the wide variety and uses of O/Ss implementing the standard, the
expectation is that the implementation will have a default that makes
sense in its context.
4. schedpolicy
The standard is clear that the default value of the schedpolicy
attribute is "unspecified". A conforming system is free to choose any
value for this field and a conforming application must correctly
handle any value. The application can specify the value of the
schedpolicy by setting it in the attribute object using the function
pthread_attr_setschedpolicy. The interpretations committee believes
that this was the intent of the working and balloting groups. Due to
the wide variety and uses of O/Ss implementing the standard, the
expectation is that the implementation will have a default that makes
sense in its context.
5. schedparms
The standard is clear that the default value of the schedparms
attribute is unspecified. A conforming system is free to choose any
value for this field and a conforming application must correctly
handle any value. The application can specify the value of schedparms
by setting it in the attribute object using the function
tthread_attr_setschedparm. The interpretations committee believes
that this was the intent of the working and balloting groups. Due to
the wide variety and uses of O/Ss implementing the standard, the
expectation is that the implementation will have a default that makes
sense in its context.
6. pthread_setspecific
The standard is clear in defining the circumstances under which lost
storage of infinite loops may occur as a result of using thread
specific data. The statement in section 17.1.2.2, lines 72-74 that
"calling pthread_setspecific() from a destructor may result in lost
storage or infinite loops" is clarified by the description of
destructor behavior in section 17.1.1.2, lines 26-33. In particular,
the circumstances under which an infinite loop or lost storage might
occur are described, those being when
{PTHREAD_DESTRUCTOR_ITERATIONS} iterations of destructor calls have
been made and non-NULL key values remain. As such, calling
pthread_setspecific() specifying a NULL value is always safe (even in
destructors) since it will not result in such storage loss or
infinite loops.
Interpretation request number 8 raised a related issue -- asking
under what circumstances a thread-specific data value is set to NULL
during destructor calls. The standard currently only describes one
way -- an explicit call to pthread_setspecific(key, NULL). The
interpretations committee believes that it was the intent of the
working and balloting groups that the thread-specific data value
associated with a key should automatically set to NULL before the
destructor is called in order to prevent infinite loops. Otherwise
each destructor function would have to somehow determine the key for
which it was invoked and do a pthread_setspecific(key, NULL) in order
to prevent infinite loops.
7. Can't set thread scheduling parameters from another process
The standard is clear that it does not define any interfaces to
provide this function. The interpretations committee believes that
this was the intent of the working and balloting groups in order to
allow the widest possible types of implementations and, specifically,
library level implementations would not be able to expose such a
system call to another process.
8. protocol
The standard is clear that the default value of the protocol
attribute is "unspecified". A conforming system is free to choose any
value for this field and a conforming application must correctly
handle any value. The application can specify the value of the
protocol by setting it in the attribute object using the function
pthread_mutexattr_setprotocol and then using the attribute object for
the creation of a mutex. The interpretations committee believes that
this was the intent of the working and balloting groups.
9. PTHREAD_PRIO_PROTECT
The standard is clear on pages 305-6 lines 701-705 that the process
executes at the higher of its priority or that of prioceiling. On
pages 287-8, the model of scheduling is clear that, conceptually,
there is an ordering for all possible priority values, independent of
scheduling policy. In the case that the effective priority range of
Sched-RR is higher than that of Sched-FIFO, then the mechanisms
provided to guard against priority inversion would likely be
unsuccessful, should any Sched_RR threads use the mutex. The
interpretations committee believes that this was the intent of the
working and balloting groups. Note also that the standard does not
require that the priority_ceiling value be a valid priority level for
the class of a locking thread. A thread's priority is not affected
by its inheritance, only its execution. See also interpretation #10.
10. PTHREAD_PRIO_INHERIT
The standard is clear on pages 287-8 that the specification of a
scheduling policy is in the context of a conceptual model that
requires specifying the relationship between the different polices.
The system is to execute the thread with the highest effective
priority independent of scheduling policy. To achieve this, it may
be necessary for a thread's effective priority to be set to a value
outside its policy's priority range.
11. Fork Handlers
The standard is clear that memory allocated as thread-specific data
for threads other than the forking thread might be leaked in the
child process if not freed or otherwise accounted for at fork time
since only a copy of the thread that called fork() will exist in the
child process. This is the intended behavior.
Three mechanisms that applications can use to eliminate this leakage
are described in the rationale in section B.3.1.3. (1) Perform an
exec() call. (2) Use the pthread_atfork() prepare handler to clean
up any state associated with other threads before the fork() is
executed. (3) Use the pthread_atfork() child handler to clean up any
state associated with other threads after the fork() is executed.
12. Signal value returned by sigpending()
The standard is clear that the set of signals returned by
sigpending() consists of all of those signals that are blocked from
delivery and are pending on either the process or the calling thread.
Equivalently, this is the union of the following two sets of signals:
1. The set of signals that are blocked from delivery and pending on
the process.
2. The set of signals that are blocked from delivery and pending on
the calling thread.
13. SIGEV_THREAD
The standard is clear on page 74 lines 696-698 that each execution of
the signal handler shall be executed in an environment as if it were
the start routine of a new thread. The interpretations committee
notes that the language in subclause 14.2.2.2 specifying the
notification semantics for timer expiration was changed by 9945-1i to
explicitly refer to 3.3.1.2. It is unspecified as to whether
multiple signals would be executed sequentially or in parallel:
conforming systems are free to do either and conforming applications
shall handle the case of parallel execution. The interpretation
committee believes that this was the intent of the working and
balloting groups in order to allow a wide range of implementations.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-04
Topic: pthread_atfork - Headers and Functions
9945-1-amd2-95 #4
Topic: pthread_atfork - Headers and Functions
Relevant Sections: 3.1.3.1 lines 79-81 , 2.7.3
Defect Report:
-----------------------
Which header is the function pthread_atfork() defined in?
Should it be pthread.h. At the moment this
has been ommitted from that header. Was this intentional?
Interpretation response
------------------------
The 9945-1-amd1 standard, to which 9945-1-amd2 is an amendment, on page
39 section 2.7.3 lines 1119 to 1121, states that "if a function is not
listed below, it shall have its prototype appear in <unistd.h>..".
pthread_atfork is not listed, so the standard is clear that it shall be
listed in <unistd.h>.
Rationale
-------------
None
WG15 Defect Report Ref: 9945-1-amd2-06
Topic: 6.7.1.1
9945-1-amd2-95 #6
Topic: 6.7.1.1
Relevant Sections: _POSIX_PRIORITIZED_IO
Defect Report:
-----------------------
FOR ISO/IEC 9945-1-amd2-1995:
1c1. Subsection 6.7.1.1:
The first sentence of the fifth paragraph of section 6.7.1.1
says "If {_POSIX_PRIORITIZED_IO} and {_POSIX_PRIORITY_SCHEDULING}
are defined, then asynchronous I/O is queued in priority order,
with the priority of each asynchronous operation based on the
current scheduling priority of the calling process." The
statement is ambiguous when the calling process is multi-threaded.
If a multi-threaded process initiates async I/O requests from
threads of various priorities, what is the "priority of the
requesting process" for each such request - the priority of the
requesting thread, or something else? This is ill-defined, as a
multi-threaded process may have several priorities.
Assuming that the interpretation answers "the priority of the
requesting thread" to the above question, I suggest that the word
"process" in the sentence be changed to "thread". Another
possibility is that it is the priority of the "initial" thread
started when the process was created, but this creates problems
for async I/O requests from other threads subsequently created
with a higher priority, since they cannot utilize their higher
priority to advantage.
Interpretation response
------------------------
The standard is clear: the priority is that of the process as set by
sched_setparam or other mechanisms. Even in the presence of threads
this remains a 'well defined' term and value. A conforming
implementation shall use that value in the calculation of the I/O
priority.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-07
Topic: PTHREAD_INHERIT_SCHED
9945-1-amd2-95 #7
Topic: PTHREAD_INHERIT_SCHED
Relevant Sections: ??
Defect Report:
-----------------------
This is a request for interpretation on an issue in the forthcoming
POSIX 9945-1-amd2, presumably 1996. Right now all I have to work from
are the draft 8 document, plus the draft 9 and 10 change documents,
but draft 10 was approved as the final specification.
My question concerns section 13.5.1.1 in draft 8 (lines 302-306) This
text was not modified by the drafts 9 or 10 changes documents.
When a thread is created with a value of PTHREAD_INHERIT_SCHED for the
inheritsched attribute, is the scheduling contention scope one of the
atributes that is inherited? Or should the new thread get the
implementation-defined default scheduling contention scope?
Interpretation response
------------------------
The standard is clear: contentionscope is one of the attributes
controlled by inheritsched.
9945-1-amd2 page 296 line 397 states:
"The contentionscope attribute defines the scheduling ...."
and on line 401 the standard uses this fact
".....set according to the other scheduling attributes in
pthread_attr_t object."
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-08
Topic: pthread_key_create()
9945-1-amd2-95 #8
Topic: pthread_key_create()
Relevant Sections: 17.1.1.2
Defect Report:
-----------------------
There seems to be an editorial error in POSIX 9945-1-amd2
regarding pthread_key_create()
The pthread_key_create section 17.1.1.2 of 9945-1-amd2 is very unclear.
As written today it easily leads one to believe that it is required that
the destructor function be called until the thread-specific value
becomes NULL, or until PTHREAD_DESTRUCTOR_ITERATIONS iterations have
occured, which ever comes first.
If you read the draft POSIX 9945-1-amd2 standard revisions, it's clear
what the intent was. Between draft standards a sentance was lost which
said "Before each destructor is called, the thread's value for the
corresponding key is set to NULL".
The re-iteration exists so that if the destructor uses keys, they will
be destroyed in a re-call to the destructor.
Was this omission an editorial error?
Interpretation response
------------------------
The standard states that the destructor is called with the current
associated value as its only argument and it is repeatedly called
until PTHREAD_DESTRUCTOR_ITERATIONS or the value associated with the
key becomes null. Conforming implementations must conform to this.
However, concerns have been raised that the intent of the working and
balloting groups was somewhat different and that the associated value
should automatically set to NULL before the destructor is called in
order to prevent infinite loops. This is needed since the destructor
function does not have a way to determine which key that caused it
to be invoked and thus does not have a way to null the value. The
committee feels that this is a problem and it is being refering it
to the sponsor for consideration.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-09
Topic: pthread_atfork()
9945-1-amd2-95 #9
Topic: pthread_atfork()
Relevant Sections: 3.1.3.1
From: Andrew Josey
Date: Wed Jul 10 15:50:23 BST 1996
Defect Report:
-----------------------
This is related to Interpretation reference 9945-1-amd2 #04
and the inter-relation between 9945-1-amd2 and 9945-2.
Interpretation 9945-1-amd2-95 #04 stated:
The 9945-1-amd1 standard, to which 9945-1-amd2 is an amendment, on
page 39 section 2.7.3 lines 1119 to 1121, states that "if a function is
not listed below, it shall have its prototype appear in <unistd.h>..".
pthread_atfork is not listed, so the standard is clear that it shall be
listed in <unistd.h>.
9945-2 states that the functions in <unistd.h> are made
available, when -l c is the argument to c89:
POSIX.2 lines 167-169 page 691 states " -l c This
library contains all library functions referenced in <stdlib.h>,
<stdio.h>,
<time.h>, <setjmp.h>, <signal.h>, <unistd.h>...".
Is it thus the correct interpretation for 9945-1-amd2 that
the pthread_atfork() function be in the standard library
found with the -l c argument?
I'd propose that this be in a libary other than that
named found by "-l c".
Interpretation response
------------------------
The response of the 9945-1-amd2 Interpretations committee is:
The standard is clear that pthread_atfork() is made available by the
-l c argument to c89. As stated in interpretation 9945-1-amd2 #4:
The 9945-1-amd1 standard, to which 9945-1-amd2 is an amendment,
on page 39 section 2.7.3 lines 1119 to 1121, states that "if a
function is not listed below, it shall have its prototype appear
in <unistd.h>.". pthread_atfork is not listed, so the standard
is clear that it shall be listed in <unistd.h>.
and 9945-2 says:
the functions in <unistd.h> are made available when -l c is the
argument to c89.
However, it is the belief of the interpretations committee that this
is not what was intended by the working group or the balloting group.
The rationale in informative annex C, page 593, line 183, lists
pthread_atfork() as being defined in <pthread.h>. Additionally, the
"pthread_" function is the only one made available by the -l c
argument to c89 is pthread_atfork(), which does not give the user of
the standard a useful set of functions. This issue is being referred
to the sponsor for consideration.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-10
Topic: cancellation points
9945-1-amd2-95 #10
Topic: cancellation points
Relevant Sections: 18.1.2
Defect Report:
-----------------------
Section 18.1.2 has the wording:
"A cancellation point may also occur when a thread is
executing the following functions"
This is incorrect and doesn't explain the intent of this section.
According to the current wording, an implementation is not required to
support cancellation. The definition of "may" according to this document
is "..., the feature or behavior is optional." This means that an
implementation is allowed to disable cancelability within these
functions.
The actual intent of POSIX is to say that these functions are
cancellation points if they happen to block during the course of the
function call. For all functions listed, sometimes they may block,
sometimes they may not.
The wording as stated is incorrect and allows for incorrectly coded
implementations.
An interpretation is requested to clarify the intended behavior of these
interfaces with respect to cancellation. We believe the following change
is the intent.
Change the wording:
"A cancellation point may also occur when a thread is
executing the following functions:"
To:
"A cancellation point will also occur in the following
functions if the function causes the thread to block:"
Interpretation response
------------------------
The "intent" is that the functions listed in ISO 9945-1:1996 following
line 56 in 18.1.2 are allowed to be cancellation points, just in
case they are implemented using other routines specified to be
cancellation
points.
Were it not for this language, these routines cannot use routines which
are cancellation points in their implementation because the standard says
that no POSIX/ISO C routines other than those specified are cancellation
points.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-11
Topic: sigpending()
9945-1-amd2-11
Topic: sigpending()
Relevant Sections: 3.3.6.2
Defect Report:
-----------------------
Section 3.3.6.2 states "are pending either for the process or the
calling thread".
The present wording text allows for implementations that differ
severely and impacts application portability.
This should be better restated as "the union of signals pending for
the process and calling thread". The intent is to return the set
of signals which are pending and may be processed by the calling
thread, whether pending on the thread or the process (ie, the
union of the process and thread pending signals).
By saying "either the process or the calling thread", an implementation
is allowed to return one or the other. If system A returns pending
signals for the calling thread, and system B returns pending signals for
the process, applications will not be portable.
This needs clarification.
We believe the wording could be better phrased as
"the union of signals pending for the process and calling
thread which are blocked from delivery for the calling
thread"
Interpretation response
------------------------
This is a duplicate of ISO/IEC 9945-1-amd2 Interpretation Request #3
subquestion 12
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-12
Topic: thread specific data
9945-1-amd2-95 #12
Topic: thread specific data
Relevant Sections: 3.1.3.2
Defect Report:
-----------------------
Section 3.1.3.2, page 27 D10, lines 84-94
This function allows an application to essentially install cancellation
type handlers to guarantee that the proper state is maintained in the
child process after a fork.
What is supposed to happen with allocated thread-secific data in the
child process? These functions are, in effect, executed by the thread
calling fork. If the other threads have allocated a lot of thread-specific
data, there is no way for the process to release that memory. The child
has immediately inherited a memory leak when using TSD. Is this intended?
There is no way of using pthread_atfork() to release other threads' thread
specific data.
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 11
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-13
Topic: sigevent structure
9945-1-amd2-95 #13
Topic: sigevent structure
Relevant Sections: 6.7.1.1 (POSIX 9945-1-amd1-93)
Defect Report:
-----------------------
Section --> None in 9945-1-amd2 D10, corresponding section in
9945-1-amd1 is:
Section 6.7.1.1
The behavior is specified when a sigevent structure of type SIGEV_NONE
or type SIGEV_SIGNAL is passed.
POSIX.1c does not specify what the behavior is if the sigevent structure
specifies SIGEV_THREAD.
The behavior needs to be specified. According to the current
definitions, these functions are not required to support SIGEV_THREAD,
even if POSIX_THREADS is defined. They define SIGEV_SIGNAL AND SIGEV_NONE,
but not SIGEV_THREAD.
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 13
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-14
Topic: stacksize
9945-1-amd2-95 #14
Topic: stacksize
Relevant Sections: 16.1.1.2
Defect Report:
-----------------------
Section 16.1.1.2, page 141 D10, lines 74-78
A default value of the stacksize attribute is not specified. The behavior
is specified if an application wants to specify their own stack size.
It does not specify the value of stacksize if the user wants the
implementation to use a default stacksize.
What is the correct stacksize to return as a default value when the user
has not specified a stacksize? Some implementations specify a default
value of 0 for a default stack. Other implementations specify a default
value of PTHREAD_STACK_MIN. This confusion can lead to source code
portablity problems.
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 2.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-15
Topic: default value for attribute
9945-1-amd2-95 #15
Topic: default value for attribute
Relevant Sections: 13.5.1.2
Defect Report:
-----------------------
Section 13.5.1.2, page 121 D10, lines 316-332
A default value for the inheritched attribute is not specified. The
default behavior needs to be specified for portable applications or
it could result in differing behavior across platforms.
What is the default value for inheritched?
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 3
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-16
Topic: sigpending
9945-1-amd2 #16
Topic: sigpending
Relevant Sections: 3.3.6.2
Defect Report:
----------------------
Section 3.3.6.2, page 39 D10, lines 492-494
This section states that sigpending() returns the signals pending on
"either" the process or the thread. The way stated, an implementation is
allowed to return process pending signals or thread pending signals.
An application cannot portably use and rely on what this function does
because of "either".
What the actual intent to say something more like "returns the union of
the signals pending on the process and the calling thread"?
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 12
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-18
Topic: stackaddr attribute
9945-1-amd2-95 #18
Topic: stackaddr attribute
Relevant Sections: 16.1.1.2
Defect Report:
--------------------
Section 16.1.1.2, page 141 D10, lines 79-83
A default value for the stackaddr attribute is not specified. The
bahvior is specified if an application wants to specify their own stack.
It does not specify what to do if they want to implementation to create a
stack for them.
Additionally, since a default value is not specified AND it is not
specified that by default the implementation allocates a stack, the
programmer must always check the default value of this attribute before
creating a thread.
What is the default value of this attribute? NULL to signify the user
wants the implementation to allocate stacks?
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 1.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-19
Topic: sched_setparam
9945-1-amd2-95 #19
Topic: sched_setparam
Relevant Sections: 13.3.3.2
Defect Report:
-----------------------
Section 13.3.1.2, page 114 D10, lines 30-36
Section 13.3.3.2, page 114 D10, lines 42-48
According to the new rules for scheduling, the sched_setparam() and
sched_setscheduler() are not useless in the presence of multithreaded
applications. The only effect these functions have is on the child
process (from fork()) of the target process. An implementation may cause
something to happen to the process scope threads, but thats all.
This provides a huge hole for system administrators. These functions have
a process parameter. This means they were intended so that a process
could control the policy and priority of another process. If that wasn't
the case, there wouldn't have been a pid as a parameter. Up until now
a system administrator could control a process if it was getting too
much or too little time on the system. Runaway processes with high
priority could be habndled.
With the new behavior, there is no way a sysadmin (or any process) can
control the behavior of a multithreaded process. If some event happens
requiring a change in the policy/priority of the MT process, only the
process itself can do it.
The worst part is that if one thread in the process goes out of control
while high prio SCHED_FIFO, no one can control it. A sysadmin cannot
do anything to lower that thread's priority (thread IDs are not
guaranteed to be known outside of the system).
Is this the actual intended behavior?
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 7
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-20
Topic: protocol attribute etc
9945-1-amd2-95 #20
Topic: protocol attribute etc
Relevant Sections: 13.6.1.2
Defect Report:
-----------------------
1) Section 13.6.1.2, page 128-129 D10, lines 581-587
What is the default value of the protocol attribute?
2) Section 13.6.1.2, page 128-129 D10, lines 578-580, 595-606
PTHREAD_PRIO_PROTECT
This states that a) the priority of the locking thread shall raise its
priority to the mutex prioceiling and b) that prioceiling must be a
valid priority for SCHED_FIFO.
What happens if the locking thread is not SCHED_FIFO? Chances are pretty
good that the prioceiling value is not a valid priority for the
scheduling policy of the thread. Even if the thread is SCHED_RR the value
may not be valid. Do these functons imply that you must also change the
scheduling policy of the locking thread to SCHED_FIFO? If so, what happens
if the system defines SCHED_FIFO to have lower priorities than say
SCHED_RR and the thread is under SCHED_RR?
3) Section 13.6.1.2, page 128-129 D10, lines 590-594
PTHREAD_PRIO_INHERIT
This states that the blocking thread shall raise the priority of the
thread owning the mutex to equal that of the blocking thread.
Only the priority is being changed here. What happens if the threads are
in different scheduling policies? The new priority may not be valid in
that scheduling policy. Is it assumed that these functions also change the
policy of the thread if they are different?
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 8.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-21
Topic: timers and SIGEV_THREAD
9945-1-amd2-95 #21
Topic: timers and SIGEV_THREAD
Relevant Sections: 14.2.2.2 (9945-1-amd1)
Defect Report:
-----------------------
Section --> None in 9945-1-amd2 D10, corresponding section in
9945-1-amd1 is Section 14.2.2.2
The behavior for timer_create() specifies what happens when a sigevent
structure of type SIGEV_NONE or type SIGEV_SIGNAL is passed to the
function. POSIX.1c does not specify what the behavior of this function is
if the sigevent structure is for SIGEV_THREAD. The most complicated part
is when sigevent specifies SIGEV_THREAD but the timer is a reloading timer
so that it continually expires.
What is supposed to happen with timers and SIGEV_THREAD? A thread is to
be created when the timer expires? What happens with reloading timers
which continually expire? Does only one thread get created and from then
on an overrun count is incremented? Since these threads are detached, you
have no way of knowing this thread terminates in order to stop
incrememnting the count and create a new thread on the next timer
expiration.
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 13.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-22
Topic: pthread_setspecific
9945-1-amd2-95 #22
Topic: pthread_setspecific
Relevant Sections: 17.1.2.2
Defect Report:
-----------------------
Section 17.1.2.2, page 166 D10, lines 192-195
This paragraph states that calling pthread_setspecific() from within a
destructor function may result in lost storage or infinite loops.
This can be a real problem. POSIX.1c has just stated that it is impossible
to use thread-specific data in an application. A portable and correctly
behaving application cannot rely on calling pthread_setspecific() from
within a destructor function.
What makes thread-specific data impossible to use is the fact that in
pthread_key_create() it is stated that when a thread terminates, any
non-NULL TSD values which have destructors will have the destructor
called for them. The problem here is that the destructor function is
called in a loop (potentially forever - so a portable application has to
assume forever) until the key value is NULL. However, according to
pthread_setspecifc() a portable and correctly behaving application has no
way possible to change the key value to a NULL value.
Portable application have to rely on "worst case" guaranteed behavior.
According to the definitions of pthread_setspecific() and
pthread_key_create() an application cannot reliably make use of
thread-specific data with destructor functions or its thread will end up
in an infinite loop.
Could you please clarify the intended behavior of these functions?
Obviously there must be something missing here or this looping behavior
for destructor functions would not have been added since an application
must assume it results in an infinite loop.
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 6.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-24
Topic: schedpolicy etc
9945-1-amd2-95 #24
Topic: schedpolicy etc
Relevant Sections: 13.5.1.2
Defect Report:
-----------------------
1) Section 13.5.1.2, page 122 D10, lines 333-342
A default value for the schedpolicy attribute is not specified.
What is the default value for this attribute?
2) Section 13.5.1.2, page 122 D10, lines 353-357
A default value for the schedparam attribute is not specified.
What is the default value for this attribute? Implementations are
already providing different values (drastically) which will effect
portability. Some implementations consider the default value
to be NULL, others return an actual value for this attribute as the
default value. This case is not merely different default values,
but actual differences in what this attribute represents. This
impacts portability.
What is the default value/behavior of this attribute?
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #3, part 5.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-27
Topic: pthread_mutexattr_init Errors
9945-1-amd2-95 #27
Topic: pthread_mutexattr_init Errors
Relevant Sections: 11.3.1.4
Defect Report:
-----------------------
1. Section 11.3.1.4, pthread_mutexattr_init Errors
pthread_attr_init and pthread_condattr_init both document ENOMEM as
an "if occurs" error, but pthread_mutexattr_init documents ENOMEM
as an "if detected" error. There is no reasonable justification for
this difference, so clearly the specification of ENOMEM in the
description of pthread_mutexattr_init was an oversight, and should
be corrected.
REF: page 254, section 11.3.1.4, line 472
page 260, section 11.4.1.4, line 685
page 335, section 16.2.1.4, line 95
Interpretation response
------------------------
The standards states that for the pthread_mutexattr_init() function
ENOMEM is an "if detected" error and conforming implementations
must conform to this. However, concerns have been
raised about this which are being referred to the sponsor."
Rationale
-------------
This appears to be a defect.
None.
WG15 Defect Report Ref: 9945-1-amd2-28
Topic: Waiting on a Condition Errors
9945-1-amd2-95 #28
Topic: Waiting on a Condition Errors
Relevant Sections: 11.4.4.4
Defect Report:
-----------------------
2. Section 11.4.4.4, Waiting on a Condition Errors
All error conditions, except ETIMEDOUT for pthread_cond_timedwait,
are reported by returning EINVAL. One of the error conditions in
particular, "the mutex was not owned by the current thread at the
time of the call" is an error that would be detected by unlocking
the specified mutex prior to waiting. This same error is reported
by pthread_mutex_unlock by returning the error EPERM. The standard
should not report the same error in different places using
different error codes. This error should be reported by returning
EPERM for both pthread_cond_wait and pthread_cond_timedwait.
REF: page 266, section 11.4.4.4, lines 898,899
page 258, section 11.3.3.4, line 615
Interpretation response
------------------------
The standard is clear that pthread_cond_timedwait should report EINVAL
when the mutex was not owned by the current thread at the time of the call
and a conforming implementation must return that value. The
interpretations committee believes that this is not what was intended and
has referred the issue to the sponsor for consideration.
Rationale
-------------
None.
WG15 Defect Report Ref: 9945-1-amd2-32
Topic: Thread-Specific Data Key Creation Description
9945-1-amd2-95 #32
Topic: Thread-Specific Data Key Creation Description
Relevant Sections: 17.1.1.2
Defect Report:
-----------------------
6. Section 17.1.1.2, Thread-Specific Data Key Creation Description
The description of thread-specific data destructors, somewhere
along the line, lost the original intent of the working group, that
the implementation shall set the thread-specific data value to NULL
prior to calling the application's destructor routine. The standard
currently (and incorrectly) requires that the application set the
value to NULL within the destructor in order to avoid infinite
looping or memory leakage. The standard should be corrected to
require that the implementation SHALL set the value to NULL before
calling the application destructor function.
REF: page 343, section 17.1.1.2, lines 20-33
Interpretation response
------------------------
This is a duplicate. See 9945-1-amd2 Interpretation #8.
Rationale
-------------
None.
_________________ end of SC22 N2594 _______________________________