Multithreaded Macro Support wrapper proposal

Steven D. Morrey smorrey at ldschurch.org
Fri Aug 21 19:35:17 CEST 2009


Hello everyone,

As you may already be aware, I have been investigating the possibility of moving 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 multi-threaded support and it was getting stomped on.

To that end I have decided to robustify the macro system by creating a handful 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 

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 = 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 SOMEMACRO 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 predict anything too drastic, and I think the benefits will outweigh the costs 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 with 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]!=NULL)
		free(macro_x[MACRO_LASTSERVICESTATECHANGE]);
	macro_x[MACRO_LASTSERVICESTATECHANGE]=(char *)malloc(MAX_DATETIME_LENGTH);
	if(macro_x[MACRO_LASTSERVICESTATECHANGE]!=NULL){
		snprintf(macro_x[MACRO_LASTSERVICESTATECHANGE],MAX_DATETIME_LENGTH,"%lu",(unsigned long)svc->last_state_change);
		macro_x[MACRO_LASTSERVICESTATECHANGE][MAX_DATETIME_LENGTH-1]='\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 anything 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 all copies of the original message.



------------------------------------------------------------------------------
Let Crystal Reports handle the reporting - Free Crystal Reports 2008 30-Day 
trial. Simplify your report design, integration and deployment - and focus on 
what you do best, core application coding. Discover what's new with 
Crystal Reports now.  http://p.sf.net/sfu/bobj-july




More information about the Developers mailing list