[Nagios-devel] Multithreaded Macro Support wrapper proposal

Support forum for Nagios Core, Nagios Plugins, NCPA, NRPE, NSCA, NDOUtils and more. Engage with the community of users including those using the open source solutions.
Locked
Guest

[Nagios-devel] Multithreaded Macro Support wrapper proposal

Post by Guest »

Hello everyone,

As you may already be aware, I have been investigating the possibility of m=
oving the high priority event list into it's own thread.
That turned out to be the easy part,.
When I tested it out I realized the macro system was never designed for mul=
ti-threaded support and it was getting stomped on.

To that end I have decided to robustify the macro system by creating a hand=
ful of wrapper functions that will make the macros thread safe (as long as =
all macro calls are passed through them).
These functions are

sprintf_macro_data
set_macro_data
get_macro_data
free_macro_data


The functions create and enforce thread safety through a couple of methods.
First off, mutexes are used to keep more than one hand at a time out of the=
cookie jar.
Secondly, there is no shared mutable data=20

Data returned from get_macro_data is a copy rather than the raw data itself.
To eliminate a bunch of boiler plate code, set_macro_data calls free_macro_=
data to free it's old copy of the data first.
Additionally, set_macro_data creates it's own copy of the data passed in to=
it, leaving the callee's copy alone.

Now each thread will be provided with it's own copy of the macro data upon =
request.
This way the callee can do whatever it wants with it's own copy of the data=
at it's leisure, a side benefit is this can prevent double free and memory=
corruption conditions.

So how do you update macro data now?
It's quite simple really
We use get, modify and set

For instance...
Previously it would have been
dosomething(macro_x[SOMEMACRO]);

Now it's
char * data =3D get_macro_data(macro_x,SOMEMACRO);
dosomething(data);
set_macro_data(data);
free(data);

The problem with the previous method is that one thread may try to free SOM=
EMACRO at the same time it's being used by another thread.

There will be a slight performance hit for doing it this way, but I don't p=
redict anything too drastic, and I think the benefits will outweigh the cos=
ts in the long term.
The fact is we don't update macros that many places in the code base, it's =
all get, set or free for the most part, so a performance hit in the update =
section should be negligible.

There are additional benefits as well.
Thus far, I have managed to replace large sections of boiler plate code wit=
h the thread safe versions, for instance.

In grab_service_macros
There are several sections that look like this...
/* get the last state change time macro */
if(macro_x[MACRO_LASTSERVICESTATECHANGE]!=3DNULL)
free(macro_x[MACRO_LASTSERVICESTATECHANGE]);
macro_x[MACRO_LASTSERVICESTATECHANGE]=3D(char *)malloc(MAX_DATETIME_LENGTH=
);
if(macro_x[MACRO_LASTSERVICESTATECHANGE]!=3DNULL){
snprintf(macro_x[MACRO_LASTSERVICESTATECHANGE],MAX_DATETIME_LENGTH,"%lu",=
(unsigned long)svc->last_state_change);
macro_x[MACRO_LASTSERVICESTATECHANGE][MAX_DATETIME_LENGTH-1]=3D'\x0';
}

All of that code can be replaced with a single call to sprintf_macro_data
sprintf_macro_data(macro_x,MACRO_LASTSERVICESTATECHANGE,MAX_DATETIME_LENGTH=
,"%lu",(unsigned long)svc->last_state_change);


I believe at this point I've got everything covered, but if anyone sees any=
thing I may have overlooked, please let me know

Sincerely,
Steve


NOTICE: This email message is for the sole use of the intended recipient(s=
) and may contain confidential and privileged information. Any unauthorized=
review, use, disclosure or distribution is prohibited. If you are not the =
intended recipient, please contact the sender by reply email and destroy al=
l copies of the original message.







This post was automatically imported from historical nagios-devel mailing list archives
Original poster: [email protected]
Locked