Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C Programming > Re: How to Easily Make a Function Thread-Safe

Reply
Thread Tools

Re: How to Easily Make a Function Thread-Safe

 
 
CBFalconer
Guest
Posts: n/a
 
      01-12-2009
Jujitsu Lizard wrote:
>
> I have written this function. The function can be understood
> without the data type particulars.
>
> /* Returns a pointer to a string describing an event. The string
> is made for announcing events that can't be used for a
> particular intended purpose.
>
> This function is not thread-safe.
> */
> const char *LOG_event_text_desc_a(const QCHAR_TSE *in_ev) {
> static char buf[250];
>
> switch (in_ev->ev) {
> case QCHAR_EV_CHAR:
> sprintf_s(buf, sizeof(buf), "Character: %02X",
> ((int)in_ev->c) & 0xFF);
> break;
> case QCHAR_EV_BREAK:
> sprintf_s(buf, sizeof(buf), "Event: BREAK");
> break;
> case QCHAR_EV_FRAME:
> sprintf_s(buf, sizeof(buf), "Event: FRAMING_ERROR");
> break;
> case QCHAR_EV_OVERRUN:
> sprintf_s(buf, sizeof(buf), "Event: LOW_LEVEL_OVERRUN");
> break;
> case QCHAR_EV_RXOVER:
> sprintf_s(buf, sizeof(buf), "Event: RECEIVE_Q_OVERFLOW");
> break;
> case QCHAR_EV_RXPARITY:
> sprintf_s(buf, sizeof(buf), "Event: PARITY_ERROR");
> break;
> default:
> sprintf_s(buf, sizeof(buf),

"Event: INTERNAL_SOFTWARE_ERROR");
> break;
> }
> return(buf);
> }
>
> The issue with thread safety is, of course, the static buffer.


Note that threads are NOT on-topic in c.l.c. However your post
brings up a different subject. You should not use // comments in
Usenet postings, because they make a total mess when subjected to
line wrap. Secondly, you should restrict line lengths to 72 char
(67 is better), again to avoid line wrap, including in multiple
depth quotations.

I have revised your source and message to those specs as a demo. I
also consider switch cases to be label like, and thus outdent their
identifiers to the left margin.

Returning to the 'thread' problem, remember that NOTHING in the
standard library is guaranteed thread safe. So the first rule is
"avoid the standard library". The second thing is to ensure that
any data areas used are accessible only the the 'thread safe' code.

That provision you have met, except that the location (buf) is
accessible by other things. You probably want to make it something
created by malloc, return a pointer to that, and ensure that the
external (not thread safe) code frees it. You would need to ensure
that the call to malloc cannot be interrupted, or that the
interruption does not call malloc again. Since your use of sprintf
is simple, you can easily write a safe replacement.

In case you are not aware, a local static array is very much like a
global static array, except that its name is not visible outside of
the declaring function. However, its location can be returned, as
you have done.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
 
Reply With Quote
 
 
 
 
Ian Collins
Guest
Posts: n/a
 
      01-12-2009
CBFalconer wrote:
>
> Note that threads are NOT on-topic in c.l.c. However your post
> brings up a different subject. You should not use // comments in
> Usenet postings, because they make a total mess when subjected to
> line wrap. Secondly, you should restrict line lengths to 72 char
> (67 is better), again to avoid line wrap, including in multiple
> depth quotations.
>

67 character lines belong in the dark ages.

If someone is posting a sample of real code, do you really expect them
to change all the comments? Sure there are issues with // comments, but
none worth spitting the dummy over.

> I have revised your source and message to those specs as a demo. I
> also consider switch cases to be label like, and thus outdent their
> identifiers to the left margin.


That's you style, why impose it on someone else's code?

> That provision you have met, except that the location (buf) is
> accessible by other things. You probably want to make it something
> created by malloc, return a pointer to that, and ensure that the
> external (not thread safe) code frees it. You would need to ensure
> that the call to malloc cannot be interrupted, or that the
> interruption does not call malloc again.


Then your user has the added complication of remembering to free memory.
Your application has the additional overhead of dynamic allocation.
Those are probably a couple of reasons why POSIX opted for the passed in
buffer.

--
Ian Collins
 
Reply With Quote
 
 
 
 
Stephen Sprunk
Guest
Posts: n/a
 
      01-13-2009
CBFalconer wrote:
> Returning to the 'thread' problem, remember that NOTHING in the
> standard library is guaranteed thread safe. So the first rule is
> "avoid the standard library". The second thing is to ensure that
> any data areas used are accessible only the the 'thread safe' code.


This is unnecessarily restrictive. While ISO C may not guarantee any
functions to be thread safe (or reentrant), the threading standard in
use (e.g. POSIX or Win32) may. For standard library functions that
inherently cannot be made thread-safe or reentrant, e.g. because they
require static storage, there will usually be alternate versions
provided that do not have that problem (e.g. strtok() vs. strtok_r()).

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Isaac Jaffe
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      01-13-2009
Ian Collins wrote:
> CBFalconer wrote:
>

.... snip ...
>
> That's you style, why impose it on someone else's code?


Is your 'r' key broken? You seem unable to interpret "as a demo".

>
>> That provision you have met, except that the location (buf) is
>> accessible by other things. You probably want to make it
>> something created by malloc, return a pointer to that, and
>> ensure that the external (not thread safe) code frees it. You
>> would need to ensure that the call to malloc cannot be
>> interrupted, or that the interruption does not call malloc
>> again.

>
> Then your user has the added complication of remembering to free
> memory. Your application has the additional overhead of dynamic
> allocation. Those are probably a couple of reasons why POSIX
> opted for the passed in buffer.


Ingenious. Delete the part where I specify the provisions, without
even marking that a snip has occurred, and then reference POSIX,
which is off-topic on clc.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      01-13-2009
CBFalconer wrote:
> Ian Collins wrote:
>> CBFalconer wrote:
>>

> .... snip ...
>> That's you style, why impose it on someone else's code?

>
> Is your 'r' key broken? You seem unable to interpret "as a demo".
>

Not broken, merely sticky.

>>> That provision you have met, except that the location (buf) is
>>> accessible by other things. You probably want to make it
>>> something created by malloc, return a pointer to that, and
>>> ensure that the external (not thread safe) code frees it. You
>>> would need to ensure that the call to malloc cannot be
>>> interrupted, or that the interruption does not call malloc
>>> again.

>> Then your user has the added complication of remembering to free
>> memory. Your application has the additional overhead of dynamic
>> allocation. Those are probably a couple of reasons why POSIX
>> opted for the passed in buffer.

>
> Ingenious. Delete the part where I specify the provisions, without
> even marking that a snip has occurred, and then reference POSIX,
> which is off-topic on clc.


Who referenced POSIX? I mentioned it. Has your topicality tunnel
vision reached the point where solutions not mentioned in the holy
standard are considered off topic?

--
Ian Collins
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      01-13-2009
Ian Collins wrote:
> CBFalconer wrote:
>> Ian Collins wrote:
>>

.... snip ...
>>
>>> Then your user has the added complication of remembering to free
>>> memory. Your application has the additional overhead of dynamic
>>> allocation. Those are probably a couple of reasons why POSIX
>>> opted for the passed in buffer.

>>
>> Ingenious. Delete the part where I specify the provisions, without
>> even marking that a snip has occurred, and then reference POSIX,
>> which is off-topic on clc.

>
> Who referenced POSIX? I mentioned it. Has your topicality tunnel
> vision reached the point where solutions not mentioned in the holy
> standard are considered off topic?


You referenced POSIX. I stuck (fairly well) to topicality, and
mentioned some means of making his code thread safe.

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
 
Reply With Quote
 
CBFalconer
Guest
Posts: n/a
 
      01-13-2009
Stephen Sprunk wrote:
> CBFalconer wrote:
>
>> Returning to the 'thread' problem, remember that NOTHING in the
>> standard library is guaranteed thread safe. So the first rule is
>> "avoid the standard library". The second thing is to ensure that
>> any data areas used are accessible only the the 'thread safe' code.

>
> This is unnecessarily restrictive. While ISO C may not guarantee
> any functions to be thread safe (or reentrant), the threading
> standard in use (e.g. POSIX or Win32) may. For standard library
> functions that inherently cannot be made thread-safe or reentrant,
> e.g. because they require static storage, there will usually be
> alternate versions provided that do not have that problem (e.g.
> strtok() vs. strtok_r()).


If you want to use POSIX please move the thread to an appropriate
newsgroup. The same goes for using functions that are not in the C
library, apart from those you can code and display. Don't just
draw the c.l.c newsgroup further off-topic.

And what is 'unnecessarily restrictive' about understanding the
things that allow code to be thread-safe?

--
[mail]: Chuck F (cbfalconer at maineline dot net)
[page]: <http://cbfalconer.home.att.net>
Try the download section.
 
Reply With Quote
 
Ian Collins
Guest
Posts: n/a
 
      01-13-2009
CBFalconer wrote:
> Ian Collins wrote:
>> CBFalconer wrote:
>>> Ian Collins wrote:
>>>

> .... snip ...
>>>> Then your user has the added complication of remembering to free
>>>> memory. Your application has the additional overhead of dynamic
>>>> allocation. Those are probably a couple of reasons why POSIX
>>>> opted for the passed in buffer.
>>> Ingenious. Delete the part where I specify the provisions, without
>>> even marking that a snip has occurred, and then reference POSIX,
>>> which is off-topic on clc.

>> Who referenced POSIX? I mentioned it. Has your topicality tunnel
>> vision reached the point where solutions not mentioned in the holy
>> standard are considered off topic?

>
> You referenced POSIX. I stuck (fairly well) to topicality, and
> mentioned some means of making his code thread safe.
>

Oh come on, I said "POSIX opted for the passed in buffer" and I'd hardly
call that referencing POSIX. You often mention your ggets utility, is
that off-topic on clc? There's a thread referring to "C Unleashed", is
that off-topic on clc?

--
Ian Collins
 
Reply With Quote
 
Stephen Sprunk
Guest
Posts: n/a
 
      01-13-2009
CBFalconer wrote:
> Stephen Sprunk wrote:
>> CBFalconer wrote:
>>> Returning to the 'thread' problem, remember that NOTHING in the
>>> standard library is guaranteed thread safe. So the first rule is
>>> "avoid the standard library". The second thing is to ensure that
>>> any data areas used are accessible only the the 'thread safe' code.

>>
>> This is unnecessarily restrictive. While ISO C may not guarantee
>> any functions to be thread safe (or reentrant), the threading
>> standard in use (e.g. POSIX or Win32) may. For standard library
>> functions that inherently cannot be made thread-safe or reentrant,
>> e.g. because they require static storage, there will usually be
>> alternate versions provided that do not have that problem (e.g.
>> strtok() vs. strtok_r()).

>
> If you want to use POSIX please move the thread to an appropriate
> newsgroup. The same goes for using functions that are not in the C
> library, apart from those you can code and display. Don't just
> draw the c.l.c newsgroup further off-topic.


Thread-safety was already under discussion; I made it no worse, and took
pains to give an answer that was not specific to POSIX (or Win32).

> And what is 'unnecessarily restrictive' about understanding the
> things that allow code to be thread-safe?


There are plenty of standard library functions that would require a
deliberately perverse implementation to not be thread safe and
reentrant, e.g. strlen().

On a system which does support threads, it is typical for the threading
system's standard to require most or all of the standard library
functions to be thread-safe and reentrant unless they are inherently
non-reentrant (e.g. strtok()) and to provide alternate versions of those
latter functions with a modified signature that can be made so.

Therefore, telling someone to "avoid the standard library" any time they
are working with threads is unnecessarily restrictive. Besides, the
OP's original problem had nothing at all to do with threads in the first
place!

S

--
Stephen Sprunk "Stupid people surround themselves with smart
CCIE #3723 people. Smart people surround themselves with
K5SSS smart people who disagree with them." --Isaac Jaffe
 
Reply With Quote
 
Phil Carmody
Guest
Posts: n/a
 
      01-13-2009
CBFalconer <(E-Mail Removed)> writes:
> Stephen Sprunk wrote:
>> CBFalconer wrote:
>>
>>> Returning to the 'thread' problem, remember that NOTHING in the
>>> standard library is guaranteed thread safe. So the first rule is
>>> "avoid the standard library". The second thing is to ensure that
>>> any data areas used are accessible only the the 'thread safe' code.

>>
>> This is unnecessarily restrictive. While ISO C may not guarantee
>> any functions to be thread safe (or reentrant), the threading
>> standard in use (e.g. POSIX or Win32) may. For standard library
>> functions that inherently cannot be made thread-safe or reentrant,
>> e.g. because they require static storage, there will usually be
>> alternate versions provided that do not have that problem (e.g.
>> strtok() vs. strtok_r()).

>
> If you want to use POSIX please move the thread to an appropriate
> newsgroup. The same goes for using functions that are not in the C
> library, apart from those you can code and display. Don't just
> draw the c.l.c newsgroup further off-topic.


In summary - never post anything about your own code here either,
as it's not part of the standard.

Thanks, Chuck, that's a far more terminal pronouncement than
any troll invasion could ever be.

The apart from the minor detail of how you perform a mutex, the
restrictions that being in a threaded environment impose on the
questioner's code are completely isomorphic to restrictions that
could be encountered in non-threaded code. There's no need to
actually pretend that a thing such as a thread exists in order
to answer his question. (And you'll hopefully have noticed that
the OP appeared to not be asking about how to perform a mutex.)

Phil
--
I tried the Vista speech recognition by running the tutorial. I was
amazed, it was awesome, recognised every word I said. Then I said the
wrong word ... and it typed the right one. It was actually just
detecting a sound and printing the expected word! -- pbhj on /.
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Re: How include a large array? Edward A. Falk C Programming 1 04-04-2013 08:07 PM
Boilsoft DVD Creator(Make a DVD Easily)V1.32 trsoft DVD Video 0 05-27-2010 02:37 AM
Re: How to Easily Make a Function Thread-Safe Ian Collins C Programming 4 01-13-2009 06:43 AM
Make Thousads Easily On The Internet cashgenerator Computer Support 0 06-24-2004 03:25 PM
Make Thousads Easily On The Internet cashgenerator Computer Support 4 06-24-2004 04:47 AM



Advertisments