change atexit behavior based on program status - c

I am trying register one function with atexit () that will print different messages based off of the current status of the program. I know that when you register the function with atexit you cannot pass an argument.
So, how can you pass the program status, say an integer, and make that function print different statements?
I know that I can register multiple functions, but I have to only use one.

Instead of using atexit, make use of the on_exit function which takes the status passed into exit() as one argument, and a void * that you can pass in.
int on_exit(void (*function)(int , void *), void *arg);
The on_exit() function registers the given function to be called at
normal process termination, whether via exit(3) or via return from the
program's main(). The function is passed the status argument given to
the last call
to exit(3) and the arg argument from on_exit().
The same function may be registered multiple times: it is called once for each registration.
When a child process is created via fork(2), it inherits copies of its parent's registrations. Upon a successful call to one of the
exec(3) functions, all registrations are removed.

Use a global variable. That can be read by your function registered with atexit.

Here's a different idea. Instead of using a global variable or different atexit handlers, you could use a simplr exit wrapper that prints
the desired message and then calls exit.
void my_exit(int rc)
{
/* Assuming you have enum constants ERR_1, etc,
* with expected error codes and 0 isn't an error condition. */
switch(rc) {
case ERR_1:
/* print message */
break;
case ERR_2:
/* print message */
break;
...
}
exit(rc);
}
Instead of ERR_1, etc, you could directly use integer constants or use if-else statements. Now you can pass the exit code to my_exit and use it wherever you'd use exit(). You would call it at the end of main() too with my_exit(0).

Related

Initialize global variable in Apache server

I have a simple apache web server with a hook function and a handler function.
int globalVar1;
int globalVar2;
static void register_hooks(apr_pool_t *pool)
{
globalVar1 = 9; /* or any other value... */
/* Create a hook in the request handler, so we get called when a request arrives */
ap_hook_handler(example_handler, NULL, NULL, APR_HOOK_LAST);
}
static int example_handler(request_rec *r)
{
printf("globalVar1=%d", globalVar1); /* print 9 */
globalVar2 = 9; /* or any other value... */
printf("globalVar2=%d", globalVar2); /* sometimes print 9 and sometimes not - race condition. */
/* do something... */
return OK;
}
I noticed that when I initialize globalVar1 in the hook, the variable has the same value as I initialized in the hook,
although the hook and the handler are been called on different processes.
1. what is the reason for that kind of behavior?
As a result, I decided to move the variable initialization to the handler function (globalVar2).
The problem I noticed is happening when the handler gets 2 requests at the same time and therefore the variable is not being initialized correctly.
So if I want to avoid race condition, I need to use lock on the variable initialization, but if I want to use lock, I need to initialize the lock before
and again I have the problem of initialization in multi threaded system.
2. How can I use lock in this kind of situation?
By mentioning variable initialization, I mean any initialization, even calling another function to initialize a global struct.
It could be much easier if I could share memory between the two processes (hook and handler), but from the investigation I did - it is impossible.
To make sure the initialization is done only once in a multithreaded situation, use a function CallOnce, that internally makes sure it is called exactly once.
For example: C11 threads.h call_once, or pthread_once.

Method of Passing Thread Parameters Causing Race Condition?

I have a question about a program I am writing, one which requires some multi-threading. The thread function requires a couple of parameters, which I am passing by doing the following:
Having a struct defined for the parameters (lets call it ThreadDataStruct)
Initializing this struct and filling the values (call our ThreadDataStruct instance THREAD_DATA)
Passing the values on to my thread during CreateThread by setting lpParameter to a pointer to the struct (&THREAD_DATA)
Re-cast the LPVOID to ThreadDataStruct in the thread function
The issue is that my function which creates the threads returns directly after the call to CreateThread. My question is: can returning so soon after creating the thread cause the thread to not get its parameters? If the struct was created in the function and then the function returns, won't the parameters for the thread function be destroyed if it can't get them fast enough?
Here is some POC to show what I mean:
Definition of our struct:
typedef struct ThreadDataStruct
{
int Number;
};
Our function we are running inside:
void Function()
{
ThreadDataStruct THREAD_DATA;
THREAD_DATA.Number = 1;
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFunction, &THREAD_DATA, 0, NULL);
return;
}
Our thread function:
void ThreadFunction(LPVOID lpParam)
{
ThreadDataStruct THREAD_DATA = *(ThreadDataStruct *)lpParam;
int NumberFromStruct = THREAD_DATA.Number;
return;
}
Do I need to find another way to pass the parameters safely?
Transferring comments into an answer.
Yes, you have a race condition; and yes, you need to have a different way of passing the parameters to the function safely. The variable passed to the thread function is (normally) passed by address, so it needs to last as long as the thread needs to access it. In your code, the function returns and that means the variable is no longer valid, so all hell breaks loose.
Thank you for clearing that up. What methods are there to pass the parameters safely? I guess I could put a Sleep(5000) after CreateThread(), but that obviously is not the best way to do this.
One option is to have Function() wait for the the thread to complete before it returns. Another option is to have Function() wait on a semaphore, and the ThreadFunction() would signal on the semaphore when it has finished reading its control data.
Another option, probably the best, is to have the function that calls Function() pass in a ThreadDataStruct * that can be used, and for it to keep that around until all the threads have terminated. So, if it is main() that calls Function(), then main() might have an array of ThreadDataStruct thread_params[32]; and it could pass &thread_params[i] to the ith call to Function() (probably within a loop).
void Function(ThreadDataStruct *THREAD_DATA)
{
THREAD_DATA->Number = 1;
CreateThread(NULL, 0, ThreadFunction, THREAD_DATA, 0, NULL);
}
int main(void)
{
ThreadDataStruct thread_params[32];
for (int i = 0; i < 32; i++)
Function(&thread_params[i]);
…code to wait for threads to exit…
}
Changes in Function() include:
Add argument.
Initialize argument via pointer.
Pass argument directly, not &THREAD_DATA.
Don't cast the thread function pointer type; make sure ThreadFunction() is the correct type to be called by CreateThread().
There's no virtue in a return; at the end of a void function.
No doubt there are other equivalent techniques available too; these come to mind immediately. Normally, though, the controlling code has some sort of array of the data structures available, and passes one of the elements of the array to each invocation of the thread-launching function.

why using pthread_exit?

I'm trying to figure out the usage of pthread_exit using this example code:
void* PrintVar(void* arg)
{
int * a = (int *) arg; // we can access memory of a!!!
printf( "%d\n", *a);
}
int main(int argc, char*argv[])
{
int a, rc;
a = 10;
pthread_t thr;
pthread_create( &thr, NULL, PrintVar, &a );
//why do I need it here?//
pthread_exit(&rc); /* process continues until last
threads termintates */
there are two things I'm not quite sure about :
when we are using pthread_create - I'm passing 'a' parameter's address,
but is this paramter being "saved" under "arg" of the PrintVar function?
for example if I was using : PrintVar(void *blabla) , and wanted to pass 2 parameters from main function : int a = 10, int b= 20 .. how can I do that?
Why the pthread_exit needed? it means - wait for proccess to end - but what scenario can I get if I won't use that line?
thanks alot!
when we are using pthread_create - I'm passing 'a' parameter's address, but is this paramter being "saved" under "arg" of the PrintVar function?
The "original" a (the one defined in main) is not being copied, you are only passing around a pointer to it.
for example if I was using : PrintVar(void *blabla) , and wanted to pass 2 parameters from main function : int a = 10, int b= 20 .. how can I do that?
Put those two values in a struct and pass a pointer to such struct as argument to pthread_create (PrintVar, thus, will receive such a pointer and will be able to retrieve the two values).
and my second question is why the pthread_exit needed? it means - wait for proccess to end - but what scenario can I get if I won't use that line?
pthread_exit terminates the current thread without terminating the process if other threads are still running; returning from main, instead, is equivalent to calling exit which, as far as the standard is concerned, should "terminate the program" (thus implicitly killing all the threads).
Now, being the C standard thread-agnostic (until C11) and support for threading in the various Unixes a relatively recent addition, depending from libc/kernel/whatever version exit may or may not kill just the current thread or all the threads.
Still, in current versions of libc, exit (and thus return from main) should terminate the process (and thus all its threads), actually using the syscall exit_group on Linux.
Notice that a similar discussion applies for the Windows CRT.
The detached attribute merely determines the behavior of the system when the thread terminates; it does not
prevent the thread from being terminated if the process terminates using exit(3) (or equivalently, if the
main thread returns).

What is the difference between a thread entry function and a normal function?

I would like to know the difference between a thread entry function:
void* thread_function (void* parameter)
{
struct parameter * thread_data = (struct parameter *)parameter;
char buffer[20];
int temp;
printf_buffer(buffer);
}
and a normal function:
void printf_buffer(char *buffer)
{
printf("buffer is %s",buffer);
return;
}
I know a thread entry is called when a thread is created, and how normal functions are used.
Are there any other differences between thread entry functions and a normal functions in terms of execution , behavior, or creating instances?
There is no difference in the language between what you call a "thread function" (although Justin has edited to call it a "thread entry function") and what you call a "normal function".
With pthreads, the so-called "start routine" of a thread is a function that takes a single void* parameter and returns void*, but there's nothing to stop you calling the same function "normally".
When the start routine of a thread returns, the thread finishes execution, but that's just because the threading implementation calls it, and then finishes the thread. It's not because of anything special to do with the start routine itself.
A thread function is just the entry/exit point of a thread. The execution of that function is no different from what you refer to as a normal function.
man pthread_create defines it quite well:
http://linux.die.net/man/3/pthread_create
one major difference that has not been mentioned yet is that the thread entry should expect to operate on a stack other than the caller's. for this reason, you will often want to pass heap copies of resources as your argument when your thread is detached, then free it in the entry:
// the caller must pass a heap copy of struct parameter* arg
void* detached_entry(void* arg) {
struct parameter* parameter = (struct parameter*)arg;
...
free(parameter);
}

What is the difference between exit and return?

What is difference between return and exit statement in C programming when called from anywhere in a C program?
return returns from the current function; it's a language keyword like for or break.
exit() terminates the whole program, wherever you call it from. (After flushing stdio buffers and so on).
The only case when both do (nearly) the same thing is in the main() function, as a return from main performs an exit().
In most C implementations, main is a real function called by some startup code that does something like int ret = main(argc, argv); exit(ret);. The C standard guarantees that something equivalent to this happens if main returns, however the implementation handles it.
Example with return:
#include <stdio.h>
void f(){
printf("Executing f\n");
return;
}
int main(){
f();
printf("Back from f\n");
}
If you execute this program it prints:
Executing f
Back from f
Another example for exit():
#include <stdio.h>
#include <stdlib.h>
void f(){
printf("Executing f\n");
exit(0);
}
int main(){
f();
printf("Back from f\n");
}
If you execute this program it prints:
Executing f
You never get "Back from f". Also notice the #include <stdlib.h> necessary to call the library function exit().
Also notice that the parameter of exit() is an integer (it's the return status of the process that the launcher process can get; the conventional usage is 0 for success or any other value for an error).
The parameter of the return statement is whatever the return type of the function is. If the function returns void, you can omit the return at the end of the function.
Last point, exit() come in two flavors _exit() and exit(). The difference between the forms is that exit() (and return from main) calls functions registered using atexit() or on_exit() before really terminating the process while _exit() (from #include <unistd.h>, or its synonymous _Exit from #include <stdlib.h>) terminates the process immediately.
Now there are also issues that are specific to C++.
C++ performs much more work than C when it is exiting from functions (return-ing). Specifically it calls destructors of local objects going out of scope. In most cases programmers won't care much of the state of a program after the processus stopped, hence it wouldn't make much difference: allocated memory will be freed, file ressource closed and so on. But it may matter if your destructor performs IOs. For instance automatic C++ OStream locally created won't be flushed on a call to exit and you may lose some unflushed data (on the other hand static OStream will be flushed).
This won't happen if you are using the good old C FILE* streams. These will be flushed on exit(). Actually, the rule is the same that for registered exit functions, FILE* will be flushed on all normal terminations, which includes exit(), but not calls to _exit() or abort().
You should also keep in mind that C++ provide a third way to get out of a function: throwing an exception. This way of going out of a function will call destructor. If it is not catched anywhere in the chain of callers, the exception can go up to the main() function and terminate the process.
Destructors of static C++ objects (globals) will be called if you call either return from main() or exit() anywhere in your program. They wont be called if the program is terminated using _exit() or abort(). abort() is mostly useful in debug mode with the purpose to immediately stop the program and get a stack trace (for post mortem analysis). It is usually hidden behind the assert() macro only active in debug mode.
When is exit() useful ?
exit() means you want to immediately stops the current process. It can be of some use for error management when we encounter some kind of irrecoverable issue that won't allow for your code to do anything useful anymore. It is often handy when the control flow is complicated and error codes has to be propagated all way up. But be aware that this is bad coding practice. Silently ending the process is in most case the worse behavior and actual error management should be preferred (or in C++ using exceptions).
Direct calls to exit() are especially bad if done in libraries as it will doom the library user and it should be a library user's choice to implement some kind of error recovery or not. If you want an example of why calling exit() from a library is bad, it leads for instance people to ask this question.
There is an undisputed legitimate use of exit() as the way to end a child process started by fork() on Operating Systems supporting it. Going back to the code before fork() is usually a bad idea. This is the rationale explaining why functions of the exec() family will never return to the caller.
I wrote two programs:
int main(){return 0;}
and
#include <stdlib.h>
int main(){exit(0)}
After executing gcc -S -O1. Here what I found watching
at assembly (only important parts):
main:
movl $0, %eax /* setting return value */
ret /* return from main */
and
main:
subq $8, %rsp /* reserving some space */
movl $0, %edi /* setting return value */
call exit /* calling exit function */
/* magic and machine specific wizardry after this call */
So my conclusion is: use return when you can, and exit() when you need.
In C, there's not much difference when used in the startup function of the program (which can be main(), wmain(), _tmain() or the default name used by your compiler).
If you return in main(), control goes back to the _start() function in the C library which originally started your program, which then calls exit() anyways. So it really doesn't matter which one you use.
For the most part, there is no difference in a C program between using return and calling exit() to terminate main().
The time when there is a difference is if you've created code that will be executed after you return from main() that relies on variables local to main(). One way that manifests itself is with setvbuf():
int main(void)
{
char buffer[BUFSIZ];
setvbuf(stdout, buffer, _IOFBF, BUFSIZ);
…code using stdout…
return 0;
}
In this example, the buffer provided via setvbuf() goes out of scope when main() returns, but the code that flushes and closes stdout will be attempting to use that buffer. This leads to undefined behaviour.
The other mechanism is to invoke atexit() with a function that accesses data from main() — via a pointer. This is harder to set up as the functions called via the atexit() mechanism are not given any arguments. So, you have to do something like this:
static void *at_exit_data = 0;
static void at_exit_handler(void)
{
char *str = at_exit_data;
printf("Exiting: %s\n", str);
}
int main(void);
{
char buffer[] = "Message to be printed via functions registered with at_exit()";
at_exit_data = buffer;
at_exit(at_exit_handler);
…processing…
return 0;
}
Again, the buffer pointed at by at_exit_data has ceased to exist when the program returned from main() and so the handler function invokes undefined behaviour.
There is a related function, at_quick_exit(), but the functions registered with it are only called if the quick_exit() function is called, which precludes the functions being called after main() returns.
the return statement exits from the current function and exit() exits from the program
they are the same when used in main() function
also return is a statement while exit() is a function which requires stdlb.h header file

Resources