473,397 Members | 1,974 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,397 software developers and data experts.

The callback function parameter in multithread

I have a lot of code like this:

VOID CALLBACK TimerRoutine(PVOID lpParam)
{
long nTaskid = (long)lpParam;

GObj *obj;
if( mapThreadSafe.find( nTaskid, obj )) // mapThreadSafe is a
hash_map, thread safe
{
obj->invoke();
}
}

someone think it's inefficient and code like this:

VOID CALLBACK TimerRoutine(PVOID lpParam)
{
GObj *obj = (GObj *)lpParam;
obj->invoke();
obj->Release();
}

I was confused.I think a hash_map is good enough and payable.
it can avoid a lot of problem in a complex environment.
what is your position?

Apr 24 '06 #1
12 3648
* Darwin Lalo:
I have a lot of code like this:

VOID CALLBACK TimerRoutine(PVOID lpParam)
{
long nTaskid = (long)lpParam;

GObj *obj;
if( mapThreadSafe.find( nTaskid, obj )) // mapThreadSafe is a
hash_map, thread safe
{
obj->invoke();
}
}

someone think it's inefficient and code like this:

VOID CALLBACK TimerRoutine(PVOID lpParam)
{
GObj *obj = (GObj *)lpParam;
obj->invoke();
obj->Release();
}

I was confused.I think a hash_map is good enough and payable.
it can avoid a lot of problem in a complex environment.
what is your position?


I think it's a good idea to get rid of the void pointers (isolate any
essential usage in some common small thing down in the depths), the C
style casts (unsafe for maintenance), the misleading and generally
unreadable Hungarian prefix notation (which has no advantage today), the
unnecessary macros like VOID for void (and macros in general), and the
manual redundant resource management like obj->Release (replace with
smart pointers, above you have both a deallocation responsibility
problem and an exception unsafety problem, both solved by better way).

That will improve the code a lot, I think.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Apr 24 '06 #2
obj->Release is bad. ref_count_ptr is good. I agree.
but sometime System API need a PVOID parameter like

BOOL CreateTimer( TIMERCALLBACK Callback, PVOID Parameter, DWORD
DueTime)

The Parameter above can't be ref_count_ptr. how do I?

like this?

? struct TimerParameter{
ref_count_ptr<GObj> obj;
};

CALL {
TimerParameter *p = new TimerParameter;
CreateTimer(TimerRoutine, p, 10);
}

VOID CALLBACK TimerRoutine(PVOID lpParam)
{
TimerParameter *p = (TimerParameter *)lpParam;
ref_count_ptr<GObj> obj = p->obj;
delete p;

obj->invoke();
}

thank you,maybe I am newbie. :)

Apr 24 '06 #3
Darwin Lalo wrote:
obj->Release is bad. ref_count_ptr is good. I agree.
but sometime System API need a PVOID parameter like
You should quote context in your reply, not everyone uses google!
BOOL CreateTimer( TIMERCALLBACK Callback, PVOID Parameter, DWORD
DueTime)

The Parameter above can't be ref_count_ptr. how do I?
You can't in this case, you're stuck with what the API requires. Even
though the API uses ugly macros for parameter types, you code will
probably be easier to read if you don't.

Back to your original question, follow Alf's advice on variable names.

Considering the above CreateTimer binds an object (Parameter), to a
function (Callback), why bother with the map?
VOID CALLBACK TimerRoutine(PVOID lpParam)
{
TimerParameter *p = (TimerParameter *)lpParam;


Don't use C casts, in this case, use static_cast.

--
Ian Collins.
Apr 24 '06 #4

Ian Collins wrote:
Darwin Lalo wrote:
obj->Release is bad. ref_count_ptr is good. I agree.
but sometime System API need a PVOID parameter like
You should quote context in your reply, not everyone uses google!
BOOL CreateTimer( TIMERCALLBACK Callback, PVOID Parameter, DWORD
DueTime)

The Parameter above can't be ref_count_ptr. how do I?

You can't in this case, you're stuck with what the API requires. Even
though the API uses ugly macros for parameter types, you code will
probably be easier to read if you don't.

Back to your original question, follow Alf's advice on variable names.

Considering the above CreateTimer binds an object (Parameter), to a
function (Callback), why bother with the map?


I don't know " binds an object (Parameter), to a function (Callback) "

this is the only sentence about my question.

you mean "functor" ?
VOID CALLBACK TimerRoutine(PVOID lpParam)
{
TimerParameter *p = (TimerParameter *)lpParam;
Don't use C casts, in this case, use static_cast.

maybe reinterpret_cast
--
Ian Collins.


Apr 24 '06 #5
Darwin Lalo wrote:
BOOL CreateTimer( TIMERCALLBACK Callback, PVOID Parameter, DWORD
DueTime)

The Parameter above can't be ref_count_ptr. how do I?

You can't in this case, you're stuck with what the API requires. Even
though the API uses ugly macros for parameter types, you code will
probably be easier to read if you don't.

Back to your original question, follow Alf's advice on variable names.

Considering the above CreateTimer binds an object (Parameter), to a
function (Callback), why bother with the map?

I don't know " binds an object (Parameter), to a function (Callback) "
this is the only sentence about my question.
you mean "functor" ?

I was assuming that "TIMERCALLBACK" is a function pointer, but looking
at the function definition, maybe it isn't. What does "VOID CALLBACK"
mean? Is it a compiler extension?
VOID CALLBACK TimerRoutine(PVOID lpParam)
{
TimerParameter *p = (TimerParameter *)lpParam;


Don't use C casts, in this case, use static_cast.


maybe reinterpret_cast

No, static_cast in this case (assuming PVOID expands to void*).

--
Ian Collins.
Apr 24 '06 #6

Ian Collins wrote:
Darwin Lalo wrote:

BOOL CreateTimer( TIMERCALLBACK Callback, PVOID Parameter, DWORD
DueTime)

The Parameter above can't be ref_count_ptr. how do I?
You can't in this case, you're stuck with what the API requires. Even
though the API uses ugly macros for parameter types, you code will
probably be easier to read if you don't.

Back to your original question, follow Alf's advice on variable names.

Considering the above CreateTimer binds an object (Parameter), to a
function (Callback), why bother with the map?

I don't know " binds an object (Parameter), to a function (Callback) "
this is the only sentence about my question.
you mean "functor" ?

I was assuming that "TIMERCALLBACK" is a function pointer,


yes

typedef void (* TIMERCALLBACK) (void *);
but looking
at the function definition, maybe it isn't. What does "VOID CALLBACK"
mean? Is it a compiler extension?
"VOID CALLBACK" is just " void " ,ok?
VOID CALLBACK TimerRoutine(PVOID lpParam)
{
TimerParameter *p = (TimerParameter *)lpParam;

Don't use C casts, in this case, use static_cast.


maybe reinterpret_cast

No, static_cast in this case (assuming PVOID expands to void*).

--
Ian Collins.


Apr 24 '06 #7
Darwin Lalo wrote:
I don't know " binds an object (Parameter), to a function (Callback) "
this is the only sentence about my question.
you mean "functor" ?


I was assuming that "TIMERCALLBACK" is a function pointer,

yes

typedef void (* TIMERCALLBACK) (void *);

but looking
at the function definition, maybe it isn't. What does "VOID CALLBACK"
mean? Is it a compiler extension?

"VOID CALLBACK" is just " void " ,ok?

OK,, so back to your original question, when you call CreateTimer, you
pass in a function pointer and a pointer to an object that will be
passed to the function when the timer expires.

So the logic you had in your original function was superfluous.
provided you pass in a unique object, it will be passed to you callback.

--
Ian Collins.
Apr 24 '06 #8

Darwin Lalo wrote:
I have a lot of code like this:

VOID CALLBACK TimerRoutine(PVOID lpParam)
{
long nTaskid = (long)lpParam;

GObj *obj;
if( mapThreadSafe.find( nTaskid, obj )) // mapThreadSafe is a
hash_map, thread safe
{
obj->invoke();
}
}

someone think it's inefficient and code like this:
It is indeed.
VOID CALLBACK TimerRoutine(PVOID lpParam)
{
GObj *obj = (GObj *)lpParam;
obj->invoke();
obj->Release();
}
The above is the proper way of writing efficient code using C-style
callbacks.
I was confused.I think a hash_map is good enough and payable.
it can avoid a lot of problem in a complex environment.
what is your position?


First of all, a thread safe container is pretty much always a bad idea
because it does not work if you want to do more than one call in an
atomic sequence. This is why external locking is preferred.

Second, you don't really need a map here. Make it simple...

Apr 24 '06 #9
thank you for your straight answer

Maxim Yegorushkin wrote:
Darwin Lalo wrote:
I have a lot of code like this:

VOID CALLBACK TimerRoutine(PVOID lpParam)
{
long nTaskid = (long)lpParam;

GObj *obj;
if( mapThreadSafe.find( nTaskid, obj )) // mapThreadSafe is a
hash_map, thread safe
{
obj->invoke();
}
}

someone think it's inefficient and code like this:


It is indeed.
VOID CALLBACK TimerRoutine(PVOID lpParam)
{
GObj *obj = (GObj *)lpParam;
obj->invoke();
obj->Release();
}


The above is the proper way of writing efficient code using C-style
callbacks.
I was confused.I think a hash_map is good enough and payable.
it can avoid a lot of problem in a complex environment.
what is your position?


First of all, a thread safe container is pretty much always a bad idea
because it does not work if you want to do more than one call in an
atomic sequence. This is why external locking is preferred.

Second, you don't really need a map here. Make it simple...


my map is like this:

template<class Key,class Type>
class simple_map{
axis::CriticalSection<true> _cs;
public:
bool find(const Key& _key,Type& _val){
axis::CriticalSectionLock lock(_cs);
std::map<Key,Type>::const_iterator _ite = _map.find(_key);
if( _ite == _map.end() )return false;
_val = _ite->second;
return true;
}
bool find(const Key& _key){
axis::CriticalSectionLock lock(_cs);
return ( _map.find(_key) != _map.end() );
}
template<class T,class P>
bool apply(T *_buddy, bool (T::*_fun)(Key key, Type type, P
parameter), P& _parameter){
axis::CriticalSectionLock lock(_cs);
_ite = _map.begin();
while( _ite != _map.end()){
Type& _tval = _ite->second;
const Key& _key = _ite->first;
++_ite;
if((_buddy->*_fun)(_key,_tval,_parameter))return true;
}
return false;
}
};

In my program, I have a lot of objects. I give each one a ID then put
their ptr in the map. Before using, I get it.

I am worry about the efficiency for the access is high frequency.
But I think the framework is clarity, and ID pass between function is
more clearer than object ptr.

Apr 24 '06 #10
Darwin Lalo wrote:

In my program, I have a lot of objects. I give each one a ID then put
their ptr in the map. Before using, I get it.

I am worry about the efficiency for the access is high frequency.
But I think the framework is clarity, and ID pass between function is
more clearer than object ptr.

But surely you can use the object pointer as a unique id?

--
Ian Collins.
Apr 24 '06 #11

Ian Collins wrote:
Darwin Lalo wrote:

In my program, I have a lot of objects. I give each one a ID then put
their ptr in the map. Before using, I get it.

I am worry about the efficiency for the access is high frequency.
But I think the framework is clarity, and ID pass between function is
more clearer than object ptr.
But surely you can use the object pointer as a unique id?


No. it is not a unique id.

int *p1 = new int;
delete p1;
int *p2 = new int;

(possibility) p1 == p2

But p1 is invaid. p2 is usable.

Yes, ref_count_ptr<int> can solve this problem.
But ref_count_ptr<int> is not a unique id(integral type).
--
Ian Collins.


Apr 24 '06 #12
Darwin Lalo wrote:
Ian Collins wrote:
Darwin Lalo wrote:
In my program, I have a lot of objects. I give each one a ID then put
their ptr in the map. Before using, I get it.

I am worry about the efficiency for the access is high frequency.
But I think the framework is clarity, and ID pass between function is
more clearer than object ptr.


But surely you can use the object pointer as a unique id?

No. it is not a unique id.

int *p1 = new int;
delete p1;
int *p2 = new int;

(possibility) p1 == p2

Ah, you didn't say objects are deleted from the map.

--
Ian Collins.
Apr 24 '06 #13

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
by: scott ocamb | last post by:
hello I have implemented a solution using async methods. There is one async method that can be invoked multiple times, ie there are multiple async "threads" running at a time. When these...
6
by: prettysmurfed | last post by:
Hi all I have a bit of a problem, the subject of this post is almost selfexplaing. But here goes: Heres an example of the code I want to implement, its all nice and simple, but the flaw is I...
6
by: Minfu Lu | last post by:
I have a problem dealing with passing a function address to a COM callback. I use this COM function for communicating to a hardware. My original project was written in VB. I have converted it to...
3
by: ryan.mitchley | last post by:
Hi all I have a class (cPort) that is designed to receive objects and, depending on the type, call a handler (callback) in any descendant of a cProcessBlock class. Callback functions take a...
6
by: smmk25 | last post by:
Before I state the problem, I just want to let the readers know, I am knew to C++\CLI and interop so please forgive any newbie questions. I have a huge C library which I want to be able to use in...
2
by: Evan Burkitt | last post by:
Hi, all. I have a Windows DLL that exports a number of functions. These functions expect to receive a pointer to a callback function and an opaque void* parameter. The callback functions are...
10
by: SQACPP | last post by:
Hi, I try to figure out how to use Callback procedure in a C++ form project The following code *work* perfectly on a console project #include "Windows.h" BOOL CALLBACK...
40
by: Angus | last post by:
Hello I am writing a library which will write data to a user defined callback function. The function the user of my library will supply is: int (*callbackfunction)(const char*); In my...
5
by: Jef Driesen | last post by:
I have a C DLL that I want to use from a C# project. The C header file contains these declarations: typedef void (*callback_t) (const unsigned char *data, unsigned int size, void *userdata);...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows...
0
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.