Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

boost smart_ptr and WIN32 PostThreadMessage

159 views
Skip to first unread message

fig...@yahoo.com

unread,
Jun 20, 2006, 12:26:47 PM6/20/06
to
I am looking for a simple wrapper or mechanism to send a boost
smart_ptr using WIN32 PostMessage (or PosthreadMessage). The smart_ptr
should be incremented when sent and decremented when received (or
derefenced).

WIN32 is not "C++ enabled" and thus does not allow to cast a smart_ptr
into an LPARAM or WPARAM.

Something like

DWORD nID;
HANDLE m_hBxTxThread = CreateThread (NULL, 0, MyThread, NULL, 0, &nID);

boost::smart_ptr<MyObject> pSmart( new MyObject);
pSmart->Set(100);

PostThreadMessage( nID, 0, 0, (LPARAM) pSmart );

does not work - can convert smart_ptr to LPARAM. This works but defeats
the point since reference is not incremented:

PostThreadMessage( nID, 0, 0, (LPARAM) &pSmart )

Thanks!

Joe Seigh

unread,
Jun 20, 2006, 1:52:12 PM6/20/06
to
You need to dynamically allocate a smart pointer, pass it to the other
thread which will delete it when finished. The dtor for the smart poiner
will decrement the reference count and delete the object if necessary.

boost::shared_ptr<MyObject> pShared = new boost::shared_ptr<MyObject>(new MyObject);
pShared->Set(100);
PostThreadMessage(nID, 0, 0, (LPARAM) &pSmart);


--
Joe Seigh

When you get lemons, you make lemonade.
When you get hardware, you make software.

Joe Seigh

unread,
Jun 20, 2006, 5:15:48 PM6/20/06
to

> boost::shared_ptr<MyObject> pShared = new
> boost::shared_ptr<MyObject>(new MyObject);
> pShared->Set(100);
> PostThreadMessage(nID, 0, 0, (LPARAM) &pSmart);
>
>
Note I'm assuming you're going the share the object
among threads. If you weren't, then there's no
need for a shared_ptr, just pass the object directly.

Alf P. Steinbach

unread,
Jun 20, 2006, 6:27:44 PM6/20/06
to
* fig...@yahoo.com:

> I am looking for a simple wrapper or mechanism to send a boost
> smart_ptr using WIN32 PostMessage (or PosthreadMessage). The smart_ptr
> should be incremented when sent and decremented when received (or
> derefenced).

AFAIK there's no such thing as a boost::smart_ptr.

There is however a boost::shared_ptr, and I'll assume that's what you mean.

Decrementing the reference count when receiving does not guarantee the
referred-to object's existence while it's still possibly referenced.

Instead the smart pointer's reference count should be decremented when
and only when an instance of the smart pointer is destroyed, or the
internal pointer is set to 0.

The problem you have here is a conflict between the smart pointer's
design goal of providing an object lifetime guarantee, and the
serialization + deserialization of a window message, where there is no a
priori guarantee that the deserialization will ever occur.

You need to establish that deserialization guarantee at the receiving
end, or you will either have a possible memory leak, or a possible use
of a destroyed object (undefined behavior).

Once you have established a deserialization guarantee at the receiving
end, one possibility for a serialization format is a raw pointer to a
dynamically allocated boost::shared_ptr, as explained by Joe Seigh.

A slightly more efficient possibility, when applicable, is to require
the object to be smart pointer aware, e.g. that it implements an
interface ISelfRef that provides two member functions setSelfRef()
(which stores a shared_ptr to self in the object) and removeSelfRef()
(which removes the self reference and returns the stored pointer). In
other situations, but not exactly this one,
boost::enable_shared_from_this can help with such self-references, but
the point of that mechanism is to avoid an increased reference count,
while here that increased reference reference count is the goal. Then
you can pass a a pointer to the object itself in the window message,
avoiding a costly dynamic allocation & deallocation.


> WIN32 is not "C++ enabled" and thus does not allow to cast a smart_ptr
> into an LPARAM or WPARAM.

That has nothing to do with C++ support.


> Something like
>
> DWORD nID;
> HANDLE m_hBxTxThread = CreateThread (NULL, 0, MyThread, NULL, 0, &nID);
>
> boost::smart_ptr<MyObject> pSmart( new MyObject);
> pSmart->Set(100);
>
> PostThreadMessage( nID, 0, 0, (LPARAM) pSmart );

Sharing an object between threads is generally not a good idea, but
perhaps you have good reasons. Using API-level thread creation is
generally not a good idea, and for that I doubt there are any good
reasons. Anyway, have you considered whether you can do without
multi-threading?

--
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?

0 new messages