You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@stdcxx.apache.org by "Martin Sebor (JIRA)" <ji...@apache.org> on 2006/06/28 19:57:29 UTC

[jira] Created: (STDCXX-215) stdcxx not async-cancel safe

stdcxx not async-cancel safe
----------------------------

         Key: STDCXX-215
         URL: http://issues.apache.org/jira/browse/STDCXX-215
     Project: C++ Standard Library
        Type: Improvement

    Versions: 4.1.2, 4.1.3    
 Environment: all
    Reporter: Martin Sebor


Moved from the Rogue Wave bug tracking database:

****Created By: sebor @ Apr 06, 2004 09:02:04 AM****
-------- Original Message --------
Subject: Re:  async safe IOstreams
Date: Mon, 5 Apr 2004 19:21:01 -0700 (PDT)
From: Dennis Handly <dh...@cup.hp.com>
To: sebor@roguewave.com
CC: dhandly@cup.hp.com, mahesha@india.hp.com

Do you claim the RW Standard C++ Library (iostreams in particular)
is async cancel safe?  With pthread_cancel?

We have a customer where it hangs after one thread is canceled.
(It was holding a mutex.)

#7  0x20000000797990d0:0 in _HPMutexWrapper::lock+0x70 ()
   from /usr/lib/hpux32/libstd_v2.so.1
#8  0x4014a50:0 in __rw::__rw_mutex_base::_C_acquire (this=0x795b56c4)
    at /opt/aCC/include_std/rw/stdmutex.h:254
#9  0x401b500:0 in __rw::__rw_guard::__rw_guard (this=0x7fffe200,
    __mutex=0x795b56c4) at /opt/aCC/include_std/rw/stdmutex.h:476
#10 0x40198b0:0 in std::ostream::sentry::sentry (this=0x7fffe200,
    __strm=@0x795b592000000000) at /opt/aCC/include_std/ostream:97
#11 0x4018170:0 in std::basic_ostream<char,std::char_traits<char> >& __rw::__rw_
insert<char,std::char_traits<char>,char const> (__strm=@0x795b592000000000,
    __s=0x40132f8 "****** Creation Thread ", __len=23, __width=0)
    at /opt/aCC/include_std/ostream.cc:165
#12 0x40174e0:0 in std::basic_ostream<char,std::char_traits<char> >& std::operat
or<<<std::char_traits<char> > (__strm=@0x795b59206861723e,
    __s=0x40132f8 "****** Creation Thread ")
    at /opt/aCC/include_std/ostream:510
#13 0x401e780:0 in main () at TestThread.cpp:49

Does it work on Tru64 because they have more atomic operations and don't
need mutexes as much as we do?
Since __rw_guard is used above, I don't see this is specific to aC++.
(Though I'm not sure why we need to serialize a call to good():
    _C_ok = _C_strm._C_opfx ().good ();
)

Or do you actually call pthread_setcancelstate to block and unblock?

============================================================
>From: "Hofherr, Birgit" <bi...@hp.com>
When compiling with -AA a multithreaded C++ program, and executing it, 
it hangs on a pthread_join when the thread contains cout << ..<<endl.

When the same program is compiled -AP no problem occurs.

It looks like the iostream package from libstd_v2.2 does not implement 
the lazy I/O scheme, which means the output ends up on a endl or a cin 
input. This brings up for the enclosed multithreaded program and for 
the customer who would like to have the cout << .. << endl; performed 
in one C statement write like for the -AP option.

============================================================
>From: "Hofherr, Birgit" <bi...@hp.com>
I just got this additional info from the customer:

Please add a sleep(1) before the call to pthread_cancel. I afterwards
tested the program on Tru64 and it fails without it.

The problem is that, with -AA, cout<<..<<endl; are not monolithic (i.e.:
expressed with a write(1,string,strlen(string)) contrary to the -AP
option. This is what the customer would like with -AA.

>From: "Hofherr, Birgit" <bi...@hp.com>
Some more analysis from the customer - regarding the lazy io

-----Original Message-----
>From: Vouters, Philippe 
After thorough analysis, /usr/lib/libstd_v2 (option -AA) must implement
a lazy I/O for cin, cout and cerr. This means that the operator << must
buffer data which is added a "\n" at endl time and writes out the buffer
to fd=1. If a operator >> comes up in the code stream, it must write out
cout and cerr buffers and then do input.

I believe this is the way /usr/lib/libstd works (option -AP). Anyway
this the way the customer would like and looks to work like on Tru64
with -std strict_ansi C++ compilation.

Philipppe Vouters (HP Services, Les Ulis, France)

============================================================
>From: Dennis Handly <dh...@cup.hp.com>
>From: "Hofherr, Birgit" <bi...@hp.com>
>When compiling with -AA a multithreaded C++ program, and executing it, 
>it hangs on a pthread_join when the thread contains cout << ..<<endl.

It doesn't hang on the pthread_join, it hangs after the pthread_cancel.
pthread_cancel is not supported with aC++'s runtime.

The user must not use PTHREAD_CANCEL_ENABLE unless no iostream, etc.
code is being used.

pthread_setcancelstate(3T) says:
 NOTES
      Only functions that are async-cancel safe should be called from a
      thread that is asynchronously cancelable.

>When the same program is compiled -Aa no problem occurs.

(They mean with -AP.)  There are no mutexes used.  A pthread_cancel
on a string operation may also hang things.

>This brings up for the enclosed multithreaded program and for 
>the customer who would like to have the cout << .. << endl; performed 
>in one C statement write like for the -AP option.
Birgit

This can't be done with -AA.  Each insertion is done with a mutex lock.
for -AP, there is a separate buffer with no mutexes.

>From: "Hofherr, Birgit" <bi...@hp.com>
>Please add a sleep(1) before the call to pthread_cancel. I afterwards
>tested the program on Tru64 and it fails without it.

The application needs to remove pthread_cancel or make sure
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE) is only used when not
in iostreams.

I've added code with -DWORK to disable and enable correctly.

>The problem is that, with -AA, cout<<..<<endl; are not monolithic (i.e.:
>expressed with a write(1,string,strlen(string)) contrary to the -AP
>option. This is what the customer would like with -AA.

This change can't be done.  It isn't part of RW's implementation.

>From: Vouters, Philippe 
>After thorough analysis, /usr/lib/libstd_v2 (option -AA) must implement
>a lazy I/O for cin, cout and cerr. This means that the operator << must
>buffer data which is added a "\n" at endl time and writes out the buffer
>to fd=1.

The user could do this by using strstream and fprintf.

>I believe this is the way /usr/lib/libstd works (option -AP).

-AP uses separate buffers.

>Anyway this the way the customer would like and looks to work like on Tru64
>with -std strict_ansi C++ compilation.
Philipppe Vouters (HP Services, Les Ulis, France)

I'm not sure how Tru64 can do this since they also use RW.

============================================================
>From: "Hofherr, Birgit" <bi...@hp.com>
This is the response from XXX - Is this something RW or we might consider?

-----Original Message-----
>From: Vouters, Philippe 
I do not know much about the internals of the Tru64 C++ library, but I
think this pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,&o)/
pthread_setcancelstate(o,NULL) (to restore in the case of the customer's
program the PTHREAD_CANCEL_ENABLE state) is performed inside the
library. Couldn't it be implemented inside libstd_v2 to make the
iostream async_safe ? Or by the compiler when -mt ? Kind regards from
home. Philippe Vouters (HP Services, Les Ulis, France);

============================================================

>From: Birgit Hofherr (Languages Expert Center) <bi...@rc.rose.hp.com>
A heads up - XXX have submitted a serious enhancement request to have
the aC++ iostreams behave the same way as Tru64's (compiled with -pthread
and -std strict_ansi). JAGaf18057 requests a change in either the compiler
when compiling with -mt or in the RW library so that iostreams are async-safe -
like the Tru64 implementation.

They are ready to escalate this.
Please let me know what we can do. 
Birgit

============================================================
>From: Dennis Handly <dh...@cup.hp.com>
XXX is claiming that this application works fine on Tru64.
Since you guys use RW, how does it work if the user uses pthread_cancel?

Is it because we use mutexes and Tru64 uses atomic operations?

============================================================
>From: Dennis Handly <dh...@cup.hp.com>

>From: "Hofherr, Birgit" <bi...@hp.com>
>This is the response from XXX - Is this something RW or we might consider?

Not likely.  It will make performance worse for customers that don't care
about it.

>They are ready to escalate this.
>Please let me know what we can do. 

Nothing, we will have to reject it.
Implementing it will kill performance for everyone using -mt.
The most we can do is document it in big bold letters.
============================================================

TestThread.cpp:

#include <pthread.h>
#include <unistd.h>
#include <string>
#include <iostream>
using std::string;
using namespace std;

#define THREADS_NUMBER 1000

void *faire(void *p) {
int o;
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &o);
	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &o);
	int i;
	for (i = 0; i <= 100000; i++) {
		// PROBLEM WHEN cout IS USED HERE 
#ifdef WORK
	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &o);
#endif
		cout << "C++faire ..." << (int)(long)p << endl;
#ifdef WORK
	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &o);
#endif
		// OK WITH printf
		printf("C  faire ...%d\n", (int)(long)p);
		pthread_testcancel();
		sleep(1);
	}
	return NULL;
}
int main() {
 int error;
 cout << "Test: Thread" << endl;
 pthread_t _thread[THREADS_NUMBER];
 pthread_attr_t _attributs;
	error = pthread_attr_init(&_attributs);
	if (error != 0) {
		cout << "Error attr_init" << endl;
		fprintf(stderr, "Error attr_init\n");
		return 1;
	}
	error = pthread_attr_setdetachstate(&_attributs, PTHREAD_CREATE_JOINABLE);
	if (error != 0) {
		fprintf(stderr, "Error setdetachstate\n");
		return 1;
	}
 int k, i;
 for(k=0; k < THREADS_NUMBER; k++) {
	cout << "****** Creation Thread " << k << " ******" << endl;
	cout << "* Thread " << k << " - create" << endl;
	error = pthread_create(&_thread[k], &_attributs, faire, (void*)(long)k);
	if (error != 0) {
		fprintf(stderr, "Error create\n");
		return 1;
	}
        sleep(1);
	fprintf(stderr, "* Thread %d - cancel\n", k);
	error = pthread_cancel(_thread[k]);
	if (error != 0) {
		fprintf(stderr, "Error cancel\n");
		return 1;
	}
	fprintf(stderr, "* Thread %d - join\n", k);
	error = pthread_join(_thread[k], NULL);
	if (error != 0) {
		fprintf(stderr, "Error join\n");
		return 1;
	}
	//cout << "Attente 2s ..." << endl;
	//sleep(2);
 }
cout << "Attente 4s" << endl;
sleep(4);
cout << "Test: FIN" << endl;
}

****Modified By: sebor @ Apr 06, 2004 09:04:02 AM****
-------- Original Message --------
Subject: Re: async safe IOstreams
Date: Tue, 06 Apr 2004 09:01:56 -0600
From: Martin Sebor <se...@roguewave.com>
To: Dennis Handly <dh...@cup.hp.com>
CC: mahesha@india.hp.com
References: <20...@hpcll183.cup.hp.com>

Dennis Handly wrote:
> Do you claim the RW Standard C++ Library (iostreams in particular)
> is async cancel safe?  With pthread_cancel?

No, we're certainly not that. There are mutexes all over the
place in iostreams. FWIW, I don't know of any implementation
that is.

> 
> We have a customer where it hangs after one thread is canceled.
> (It was holding a mutex.)

Right.

> 
...
> Does it work on Tru64 because they have more atomic operations and don't
> need mutexes as much as we do?

No, it's not safe on any platform.

> Since __rw_guard is used above, I don't see this is specific to aC++.
> (Though I'm not sure why we need to serialize a call to good():
>     _C_ok = _C_strm._C_opfx ().good ();
> )
> 
> Or do you actually call pthread_setcancelstate to block and unblock?

No, but it's on my to-do list.

Martin

-- 
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
   http://issues.apache.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
   http://www.atlassian.com/software/jira


[jira] Updated: (STDCXX-215) stdcxx not async-cancel safe

Posted by "Martin Sebor (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/STDCXX-215?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Martin Sebor updated STDCXX-215:
--------------------------------

    Component/s: Thread Safety
       Severity: Resource Leak

> stdcxx not async-cancel safe
> ----------------------------
>
>                 Key: STDCXX-215
>                 URL: https://issues.apache.org/jira/browse/STDCXX-215
>             Project: C++ Standard Library
>          Issue Type: Improvement
>          Components: Thread Safety
>    Affects Versions: 4.1.2, 4.1.3
>         Environment: all
>            Reporter: Martin Sebor
>            Priority: Minor
>
> Moved from the Rogue Wave bug tracking database:
> ****Created By: sebor @ Apr 06, 2004 09:02:04 AM****
> -------- Original Message --------
> Subject: Re:  async safe IOstreams
> Date: Mon, 5 Apr 2004 19:21:01 -0700 (PDT)
> From: Dennis Handly <dh...@cup.hp.com>
> To: sebor@roguewave.com
> CC: dhandly@cup.hp.com, mahesha@india.hp.com
> Do you claim the RW Standard C++ Library (iostreams in particular)
> is async cancel safe?  With pthread_cancel?
> We have a customer where it hangs after one thread is canceled.
> (It was holding a mutex.)
> #7  0x20000000797990d0:0 in _HPMutexWrapper::lock+0x70 ()
>    from /usr/lib/hpux32/libstd_v2.so.1
> #8  0x4014a50:0 in __rw::__rw_mutex_base::_C_acquire (this=0x795b56c4)
>     at /opt/aCC/include_std/rw/stdmutex.h:254
> #9  0x401b500:0 in __rw::__rw_guard::__rw_guard (this=0x7fffe200,
>     __mutex=0x795b56c4) at /opt/aCC/include_std/rw/stdmutex.h:476
> #10 0x40198b0:0 in std::ostream::sentry::sentry (this=0x7fffe200,
>     __strm=@0x795b592000000000) at /opt/aCC/include_std/ostream:97
> #11 0x4018170:0 in std::basic_ostream<char,std::char_traits<char> >& __rw::__rw_
> insert<char,std::char_traits<char>,char const> (__strm=@0x795b592000000000,
>     __s=0x40132f8 "****** Creation Thread ", __len=23, __width=0)
>     at /opt/aCC/include_std/ostream.cc:165
> #12 0x40174e0:0 in std::basic_ostream<char,std::char_traits<char> >& std::operat
> or<<<std::char_traits<char> > (__strm=@0x795b59206861723e,
>     __s=0x40132f8 "****** Creation Thread ")
>     at /opt/aCC/include_std/ostream:510
> #13 0x401e780:0 in main () at TestThread.cpp:49
> Does it work on Tru64 because they have more atomic operations and don't
> need mutexes as much as we do?
> Since __rw_guard is used above, I don't see this is specific to aC++.
> (Though I'm not sure why we need to serialize a call to good():
>     _C_ok = _C_strm._C_opfx ().good ();
> )
> Or do you actually call pthread_setcancelstate to block and unblock?
> ============================================================
> >From: "Hofherr, Birgit" <bi...@hp.com>
> When compiling with -AA a multithreaded C++ program, and executing it, 
> it hangs on a pthread_join when the thread contains cout << ..<<endl.
> When the same program is compiled -AP no problem occurs.
> It looks like the iostream package from libstd_v2.2 does not implement 
> the lazy I/O scheme, which means the output ends up on a endl or a cin 
> input. This brings up for the enclosed multithreaded program and for 
> the customer who would like to have the cout << .. << endl; performed 
> in one C statement write like for the -AP option.
> ============================================================
> >From: "Hofherr, Birgit" <bi...@hp.com>
> I just got this additional info from the customer:
> Please add a sleep(1) before the call to pthread_cancel. I afterwards
> tested the program on Tru64 and it fails without it.
> The problem is that, with -AA, cout<<..<<endl; are not monolithic (i.e.:
> expressed with a write(1,string,strlen(string)) contrary to the -AP
> option. This is what the customer would like with -AA.
> >From: "Hofherr, Birgit" <bi...@hp.com>
> Some more analysis from the customer - regarding the lazy io
> -----Original Message-----
> >From: Vouters, Philippe 
> After thorough analysis, /usr/lib/libstd_v2 (option -AA) must implement
> a lazy I/O for cin, cout and cerr. This means that the operator << must
> buffer data which is added a "\n" at endl time and writes out the buffer
> to fd=1. If a operator >> comes up in the code stream, it must write out
> cout and cerr buffers and then do input.
> I believe this is the way /usr/lib/libstd works (option -AP). Anyway
> this the way the customer would like and looks to work like on Tru64
> with -std strict_ansi C++ compilation.
> Philipppe Vouters (HP Services, Les Ulis, France)
> ============================================================
> >From: Dennis Handly <dh...@cup.hp.com>
> >From: "Hofherr, Birgit" <bi...@hp.com>
> >When compiling with -AA a multithreaded C++ program, and executing it, 
> >it hangs on a pthread_join when the thread contains cout << ..<<endl.
> It doesn't hang on the pthread_join, it hangs after the pthread_cancel.
> pthread_cancel is not supported with aC++'s runtime.
> The user must not use PTHREAD_CANCEL_ENABLE unless no iostream, etc.
> code is being used.
> pthread_setcancelstate(3T) says:
>  NOTES
>       Only functions that are async-cancel safe should be called from a
>       thread that is asynchronously cancelable.
> >When the same program is compiled -Aa no problem occurs.
> (They mean with -AP.)  There are no mutexes used.  A pthread_cancel
> on a string operation may also hang things.
> >This brings up for the enclosed multithreaded program and for 
> >the customer who would like to have the cout << .. << endl; performed 
> >in one C statement write like for the -AP option.
> Birgit
> This can't be done with -AA.  Each insertion is done with a mutex lock.
> for -AP, there is a separate buffer with no mutexes.
> >From: "Hofherr, Birgit" <bi...@hp.com>
> >Please add a sleep(1) before the call to pthread_cancel. I afterwards
> >tested the program on Tru64 and it fails without it.
> The application needs to remove pthread_cancel or make sure
> pthread_setcancelstate(PTHREAD_CANCEL_ENABLE) is only used when not
> in iostreams.
> I've added code with -DWORK to disable and enable correctly.
> >The problem is that, with -AA, cout<<..<<endl; are not monolithic (i.e.:
> >expressed with a write(1,string,strlen(string)) contrary to the -AP
> >option. This is what the customer would like with -AA.
> This change can't be done.  It isn't part of RW's implementation.
> >From: Vouters, Philippe 
> >After thorough analysis, /usr/lib/libstd_v2 (option -AA) must implement
> >a lazy I/O for cin, cout and cerr. This means that the operator << must
> >buffer data which is added a "\n" at endl time and writes out the buffer
> >to fd=1.
> The user could do this by using strstream and fprintf.
> >I believe this is the way /usr/lib/libstd works (option -AP).
> -AP uses separate buffers.
> >Anyway this the way the customer would like and looks to work like on Tru64
> >with -std strict_ansi C++ compilation.
> Philipppe Vouters (HP Services, Les Ulis, France)
> I'm not sure how Tru64 can do this since they also use RW.
> ============================================================
> >From: "Hofherr, Birgit" <bi...@hp.com>
> This is the response from XXX - Is this something RW or we might consider?
> -----Original Message-----
> >From: Vouters, Philippe 
> I do not know much about the internals of the Tru64 C++ library, but I
> think this pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,&o)/
> pthread_setcancelstate(o,NULL) (to restore in the case of the customer's
> program the PTHREAD_CANCEL_ENABLE state) is performed inside the
> library. Couldn't it be implemented inside libstd_v2 to make the
> iostream async_safe ? Or by the compiler when -mt ? Kind regards from
> home. Philippe Vouters (HP Services, Les Ulis, France);
> ============================================================
> >From: Birgit Hofherr (Languages Expert Center) <bi...@rc.rose.hp.com>
> A heads up - XXX have submitted a serious enhancement request to have
> the aC++ iostreams behave the same way as Tru64's (compiled with -pthread
> and -std strict_ansi). JAGaf18057 requests a change in either the compiler
> when compiling with -mt or in the RW library so that iostreams are async-safe -
> like the Tru64 implementation.
> They are ready to escalate this.
> Please let me know what we can do. 
> Birgit
> ============================================================
> >From: Dennis Handly <dh...@cup.hp.com>
> XXX is claiming that this application works fine on Tru64.
> Since you guys use RW, how does it work if the user uses pthread_cancel?
> Is it because we use mutexes and Tru64 uses atomic operations?
> ============================================================
> >From: Dennis Handly <dh...@cup.hp.com>
> >From: "Hofherr, Birgit" <bi...@hp.com>
> >This is the response from XXX - Is this something RW or we might consider?
> Not likely.  It will make performance worse for customers that don't care
> about it.
> >They are ready to escalate this.
> >Please let me know what we can do. 
> Nothing, we will have to reject it.
> Implementing it will kill performance for everyone using -mt.
> The most we can do is document it in big bold letters.
> ============================================================
> TestThread.cpp:
> #include <pthread.h>
> #include <unistd.h>
> #include <string>
> #include <iostream>
> using std::string;
> using namespace std;
> #define THREADS_NUMBER 1000
> void *faire(void *p) {
> int o;
> 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &o);
> 	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &o);
> 	int i;
> 	for (i = 0; i <= 100000; i++) {
> 		// PROBLEM WHEN cout IS USED HERE 
> #ifdef WORK
> 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &o);
> #endif
> 		cout << "C++faire ..." << (int)(long)p << endl;
> #ifdef WORK
> 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &o);
> #endif
> 		// OK WITH printf
> 		printf("C  faire ...%d\n", (int)(long)p);
> 		pthread_testcancel();
> 		sleep(1);
> 	}
> 	return NULL;
> }
> int main() {
>  int error;
>  cout << "Test: Thread" << endl;
>  pthread_t _thread[THREADS_NUMBER];
>  pthread_attr_t _attributs;
> 	error = pthread_attr_init(&_attributs);
> 	if (error != 0) {
> 		cout << "Error attr_init" << endl;
> 		fprintf(stderr, "Error attr_init\n");
> 		return 1;
> 	}
> 	error = pthread_attr_setdetachstate(&_attributs, PTHREAD_CREATE_JOINABLE);
> 	if (error != 0) {
> 		fprintf(stderr, "Error setdetachstate\n");
> 		return 1;
> 	}
>  int k, i;
>  for(k=0; k < THREADS_NUMBER; k++) {
> 	cout << "****** Creation Thread " << k << " ******" << endl;
> 	cout << "* Thread " << k << " - create" << endl;
> 	error = pthread_create(&_thread[k], &_attributs, faire, (void*)(long)k);
> 	if (error != 0) {
> 		fprintf(stderr, "Error create\n");
> 		return 1;
> 	}
>         sleep(1);
> 	fprintf(stderr, "* Thread %d - cancel\n", k);
> 	error = pthread_cancel(_thread[k]);
> 	if (error != 0) {
> 		fprintf(stderr, "Error cancel\n");
> 		return 1;
> 	}
> 	fprintf(stderr, "* Thread %d - join\n", k);
> 	error = pthread_join(_thread[k], NULL);
> 	if (error != 0) {
> 		fprintf(stderr, "Error join\n");
> 		return 1;
> 	}
> 	//cout << "Attente 2s ..." << endl;
> 	//sleep(2);
>  }
> cout << "Attente 4s" << endl;
> sleep(4);
> cout << "Test: FIN" << endl;
> }
> ****Modified By: sebor @ Apr 06, 2004 09:04:02 AM****
> -------- Original Message --------
> Subject: Re: async safe IOstreams
> Date: Tue, 06 Apr 2004 09:01:56 -0600
> From: Martin Sebor <se...@roguewave.com>
> To: Dennis Handly <dh...@cup.hp.com>
> CC: mahesha@india.hp.com
> References: <20...@hpcll183.cup.hp.com>
> Dennis Handly wrote:
> > Do you claim the RW Standard C++ Library (iostreams in particular)
> > is async cancel safe?  With pthread_cancel?
> No, we're certainly not that. There are mutexes all over the
> place in iostreams. FWIW, I don't know of any implementation
> that is.
> > 
> > We have a customer where it hangs after one thread is canceled.
> > (It was holding a mutex.)
> Right.
> > 
> ...
> > Does it work on Tru64 because they have more atomic operations and don't
> > need mutexes as much as we do?
> No, it's not safe on any platform.
> > Since __rw_guard is used above, I don't see this is specific to aC++.
> > (Though I'm not sure why we need to serialize a call to good():
> >     _C_ok = _C_strm._C_opfx ().good ();
> > )
> > 
> > Or do you actually call pthread_setcancelstate to block and unblock?
> No, but it's on my to-do list.
> Martin

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.


[jira] Updated: (STDCXX-215) stdcxx not async-cancel safe

Posted by "Martin Sebor (JIRA)" <ji...@apache.org>.
     [ https://issues.apache.org/jira/browse/STDCXX-215?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]

Martin Sebor updated STDCXX-215:
--------------------------------

    Priority: Minor  (was: Major)

Lowered priority.

> stdcxx not async-cancel safe
> ----------------------------
>
>                 Key: STDCXX-215
>                 URL: https://issues.apache.org/jira/browse/STDCXX-215
>             Project: C++ Standard Library
>          Issue Type: Improvement
>    Affects Versions: 4.1.3, 4.1.2
>         Environment: all
>            Reporter: Martin Sebor
>            Priority: Minor
>
> Moved from the Rogue Wave bug tracking database:
> ****Created By: sebor @ Apr 06, 2004 09:02:04 AM****
> -------- Original Message --------
> Subject: Re:  async safe IOstreams
> Date: Mon, 5 Apr 2004 19:21:01 -0700 (PDT)
> From: Dennis Handly <dh...@cup.hp.com>
> To: sebor@roguewave.com
> CC: dhandly@cup.hp.com, mahesha@india.hp.com
> Do you claim the RW Standard C++ Library (iostreams in particular)
> is async cancel safe?  With pthread_cancel?
> We have a customer where it hangs after one thread is canceled.
> (It was holding a mutex.)
> #7  0x20000000797990d0:0 in _HPMutexWrapper::lock+0x70 ()
>    from /usr/lib/hpux32/libstd_v2.so.1
> #8  0x4014a50:0 in __rw::__rw_mutex_base::_C_acquire (this=0x795b56c4)
>     at /opt/aCC/include_std/rw/stdmutex.h:254
> #9  0x401b500:0 in __rw::__rw_guard::__rw_guard (this=0x7fffe200,
>     __mutex=0x795b56c4) at /opt/aCC/include_std/rw/stdmutex.h:476
> #10 0x40198b0:0 in std::ostream::sentry::sentry (this=0x7fffe200,
>     __strm=@0x795b592000000000) at /opt/aCC/include_std/ostream:97
> #11 0x4018170:0 in std::basic_ostream<char,std::char_traits<char> >& __rw::__rw_
> insert<char,std::char_traits<char>,char const> (__strm=@0x795b592000000000,
>     __s=0x40132f8 "****** Creation Thread ", __len=23, __width=0)
>     at /opt/aCC/include_std/ostream.cc:165
> #12 0x40174e0:0 in std::basic_ostream<char,std::char_traits<char> >& std::operat
> or<<<std::char_traits<char> > (__strm=@0x795b59206861723e,
>     __s=0x40132f8 "****** Creation Thread ")
>     at /opt/aCC/include_std/ostream:510
> #13 0x401e780:0 in main () at TestThread.cpp:49
> Does it work on Tru64 because they have more atomic operations and don't
> need mutexes as much as we do?
> Since __rw_guard is used above, I don't see this is specific to aC++.
> (Though I'm not sure why we need to serialize a call to good():
>     _C_ok = _C_strm._C_opfx ().good ();
> )
> Or do you actually call pthread_setcancelstate to block and unblock?
> ============================================================
> >From: "Hofherr, Birgit" <bi...@hp.com>
> When compiling with -AA a multithreaded C++ program, and executing it, 
> it hangs on a pthread_join when the thread contains cout << ..<<endl.
> When the same program is compiled -AP no problem occurs.
> It looks like the iostream package from libstd_v2.2 does not implement 
> the lazy I/O scheme, which means the output ends up on a endl or a cin 
> input. This brings up for the enclosed multithreaded program and for 
> the customer who would like to have the cout << .. << endl; performed 
> in one C statement write like for the -AP option.
> ============================================================
> >From: "Hofherr, Birgit" <bi...@hp.com>
> I just got this additional info from the customer:
> Please add a sleep(1) before the call to pthread_cancel. I afterwards
> tested the program on Tru64 and it fails without it.
> The problem is that, with -AA, cout<<..<<endl; are not monolithic (i.e.:
> expressed with a write(1,string,strlen(string)) contrary to the -AP
> option. This is what the customer would like with -AA.
> >From: "Hofherr, Birgit" <bi...@hp.com>
> Some more analysis from the customer - regarding the lazy io
> -----Original Message-----
> >From: Vouters, Philippe 
> After thorough analysis, /usr/lib/libstd_v2 (option -AA) must implement
> a lazy I/O for cin, cout and cerr. This means that the operator << must
> buffer data which is added a "\n" at endl time and writes out the buffer
> to fd=1. If a operator >> comes up in the code stream, it must write out
> cout and cerr buffers and then do input.
> I believe this is the way /usr/lib/libstd works (option -AP). Anyway
> this the way the customer would like and looks to work like on Tru64
> with -std strict_ansi C++ compilation.
> Philipppe Vouters (HP Services, Les Ulis, France)
> ============================================================
> >From: Dennis Handly <dh...@cup.hp.com>
> >From: "Hofherr, Birgit" <bi...@hp.com>
> >When compiling with -AA a multithreaded C++ program, and executing it, 
> >it hangs on a pthread_join when the thread contains cout << ..<<endl.
> It doesn't hang on the pthread_join, it hangs after the pthread_cancel.
> pthread_cancel is not supported with aC++'s runtime.
> The user must not use PTHREAD_CANCEL_ENABLE unless no iostream, etc.
> code is being used.
> pthread_setcancelstate(3T) says:
>  NOTES
>       Only functions that are async-cancel safe should be called from a
>       thread that is asynchronously cancelable.
> >When the same program is compiled -Aa no problem occurs.
> (They mean with -AP.)  There are no mutexes used.  A pthread_cancel
> on a string operation may also hang things.
> >This brings up for the enclosed multithreaded program and for 
> >the customer who would like to have the cout << .. << endl; performed 
> >in one C statement write like for the -AP option.
> Birgit
> This can't be done with -AA.  Each insertion is done with a mutex lock.
> for -AP, there is a separate buffer with no mutexes.
> >From: "Hofherr, Birgit" <bi...@hp.com>
> >Please add a sleep(1) before the call to pthread_cancel. I afterwards
> >tested the program on Tru64 and it fails without it.
> The application needs to remove pthread_cancel or make sure
> pthread_setcancelstate(PTHREAD_CANCEL_ENABLE) is only used when not
> in iostreams.
> I've added code with -DWORK to disable and enable correctly.
> >The problem is that, with -AA, cout<<..<<endl; are not monolithic (i.e.:
> >expressed with a write(1,string,strlen(string)) contrary to the -AP
> >option. This is what the customer would like with -AA.
> This change can't be done.  It isn't part of RW's implementation.
> >From: Vouters, Philippe 
> >After thorough analysis, /usr/lib/libstd_v2 (option -AA) must implement
> >a lazy I/O for cin, cout and cerr. This means that the operator << must
> >buffer data which is added a "\n" at endl time and writes out the buffer
> >to fd=1.
> The user could do this by using strstream and fprintf.
> >I believe this is the way /usr/lib/libstd works (option -AP).
> -AP uses separate buffers.
> >Anyway this the way the customer would like and looks to work like on Tru64
> >with -std strict_ansi C++ compilation.
> Philipppe Vouters (HP Services, Les Ulis, France)
> I'm not sure how Tru64 can do this since they also use RW.
> ============================================================
> >From: "Hofherr, Birgit" <bi...@hp.com>
> This is the response from XXX - Is this something RW or we might consider?
> -----Original Message-----
> >From: Vouters, Philippe 
> I do not know much about the internals of the Tru64 C++ library, but I
> think this pthread_setcancelstate(PTHREAD_CANCEL_DISABLE,&o)/
> pthread_setcancelstate(o,NULL) (to restore in the case of the customer's
> program the PTHREAD_CANCEL_ENABLE state) is performed inside the
> library. Couldn't it be implemented inside libstd_v2 to make the
> iostream async_safe ? Or by the compiler when -mt ? Kind regards from
> home. Philippe Vouters (HP Services, Les Ulis, France);
> ============================================================
> >From: Birgit Hofherr (Languages Expert Center) <bi...@rc.rose.hp.com>
> A heads up - XXX have submitted a serious enhancement request to have
> the aC++ iostreams behave the same way as Tru64's (compiled with -pthread
> and -std strict_ansi). JAGaf18057 requests a change in either the compiler
> when compiling with -mt or in the RW library so that iostreams are async-safe -
> like the Tru64 implementation.
> They are ready to escalate this.
> Please let me know what we can do. 
> Birgit
> ============================================================
> >From: Dennis Handly <dh...@cup.hp.com>
> XXX is claiming that this application works fine on Tru64.
> Since you guys use RW, how does it work if the user uses pthread_cancel?
> Is it because we use mutexes and Tru64 uses atomic operations?
> ============================================================
> >From: Dennis Handly <dh...@cup.hp.com>
> >From: "Hofherr, Birgit" <bi...@hp.com>
> >This is the response from XXX - Is this something RW or we might consider?
> Not likely.  It will make performance worse for customers that don't care
> about it.
> >They are ready to escalate this.
> >Please let me know what we can do. 
> Nothing, we will have to reject it.
> Implementing it will kill performance for everyone using -mt.
> The most we can do is document it in big bold letters.
> ============================================================
> TestThread.cpp:
> #include <pthread.h>
> #include <unistd.h>
> #include <string>
> #include <iostream>
> using std::string;
> using namespace std;
> #define THREADS_NUMBER 1000
> void *faire(void *p) {
> int o;
> 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &o);
> 	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, &o);
> 	int i;
> 	for (i = 0; i <= 100000; i++) {
> 		// PROBLEM WHEN cout IS USED HERE 
> #ifdef WORK
> 	pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &o);
> #endif
> 		cout << "C++faire ..." << (int)(long)p << endl;
> #ifdef WORK
> 	pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &o);
> #endif
> 		// OK WITH printf
> 		printf("C  faire ...%d\n", (int)(long)p);
> 		pthread_testcancel();
> 		sleep(1);
> 	}
> 	return NULL;
> }
> int main() {
>  int error;
>  cout << "Test: Thread" << endl;
>  pthread_t _thread[THREADS_NUMBER];
>  pthread_attr_t _attributs;
> 	error = pthread_attr_init(&_attributs);
> 	if (error != 0) {
> 		cout << "Error attr_init" << endl;
> 		fprintf(stderr, "Error attr_init\n");
> 		return 1;
> 	}
> 	error = pthread_attr_setdetachstate(&_attributs, PTHREAD_CREATE_JOINABLE);
> 	if (error != 0) {
> 		fprintf(stderr, "Error setdetachstate\n");
> 		return 1;
> 	}
>  int k, i;
>  for(k=0; k < THREADS_NUMBER; k++) {
> 	cout << "****** Creation Thread " << k << " ******" << endl;
> 	cout << "* Thread " << k << " - create" << endl;
> 	error = pthread_create(&_thread[k], &_attributs, faire, (void*)(long)k);
> 	if (error != 0) {
> 		fprintf(stderr, "Error create\n");
> 		return 1;
> 	}
>         sleep(1);
> 	fprintf(stderr, "* Thread %d - cancel\n", k);
> 	error = pthread_cancel(_thread[k]);
> 	if (error != 0) {
> 		fprintf(stderr, "Error cancel\n");
> 		return 1;
> 	}
> 	fprintf(stderr, "* Thread %d - join\n", k);
> 	error = pthread_join(_thread[k], NULL);
> 	if (error != 0) {
> 		fprintf(stderr, "Error join\n");
> 		return 1;
> 	}
> 	//cout << "Attente 2s ..." << endl;
> 	//sleep(2);
>  }
> cout << "Attente 4s" << endl;
> sleep(4);
> cout << "Test: FIN" << endl;
> }
> ****Modified By: sebor @ Apr 06, 2004 09:04:02 AM****
> -------- Original Message --------
> Subject: Re: async safe IOstreams
> Date: Tue, 06 Apr 2004 09:01:56 -0600
> From: Martin Sebor <se...@roguewave.com>
> To: Dennis Handly <dh...@cup.hp.com>
> CC: mahesha@india.hp.com
> References: <20...@hpcll183.cup.hp.com>
> Dennis Handly wrote:
> > Do you claim the RW Standard C++ Library (iostreams in particular)
> > is async cancel safe?  With pthread_cancel?
> No, we're certainly not that. There are mutexes all over the
> place in iostreams. FWIW, I don't know of any implementation
> that is.
> > 
> > We have a customer where it hangs after one thread is canceled.
> > (It was holding a mutex.)
> Right.
> > 
> ...
> > Does it work on Tru64 because they have more atomic operations and don't
> > need mutexes as much as we do?
> No, it's not safe on any platform.
> > Since __rw_guard is used above, I don't see this is specific to aC++.
> > (Though I'm not sure why we need to serialize a call to good():
> >     _C_ok = _C_strm._C_opfx ().good ();
> > )
> > 
> > Or do you actually call pthread_setcancelstate to block and unblock?
> No, but it's on my to-do list.
> Martin

-- 
This message is automatically generated by JIRA.
-
You can reply to this email to add a comment to the issue online.