tags:

views:

76

answers:

4

I have the following code, which is supposed to add a shared_ptr instance to an intrusive linked list by thread A. Some other consumer thread will then use it later on by removing it from the list. However at a certain point my shared_ptr seems to get destroyed and the reference to it in the linked list is no longer valid resulting in an Assert.

Can someone enlighten me on what I am doing wrong? I suspect it is because I create my original shared_ptr in a local scope and it just gets destroyed. Although the List should still have a reference to it??? (This is NOT production code)

EDIT:

Defintiions of variables used:

BaseHookQueueList* lst;
typedef boost::intrusive::list<QueueList> BaseHookQueueList;  
class QueueList : public boost::intrusive::list_base_hook<>


//    Making my BaseHookQueueList take a shared_ptr of pointing to type QueueList conflicts //    with the list_base_hook because it does not seem to like shared_ptr...  
    ////////////////////////////////////////////////////////////////////////////////////
        if (dwWait == WAIT_OBJECT_0) //Wait is successfull
                    {
                        while(count != 100)
                        {
                            //Some new request arrived
                            boost::shared_ptr<QueueList> Qlist (new QueueList());  //Create shared_ptr instance 
                            int temp = 0;
                            if (count > 5)
                            {
                                Qlist->SetName(names[temp]);  // Fill up name property of QueueList object with some nonsense...
                                temp++;
                            }
                            else
                            {
                                Qlist->SetName(names[count]);
                            }

                            workerfunc(lst, Qlist);  // Pass to worker func
                            count++;    
                        }
                    } // shared_ptr goes out scope and I get ASSERT error from list!!
                }
        }

        void workerfunc(BaseHookQueueList* l, LIST item)  // LIST is a typedef shared_ptr<QueueList> LIST
        {
            {
                boost::mutex::scoped_lock workerfunclock(listlock);

                l->push_front(*item);  //Add to list 
            }

            //Scope of lock
            {
                boost::mutex::scoped_lock workerfuncconsoleLock(consolelock);
                printf("Adding item to list...\n");
            }

            ReleaseSemaphore(hConsumer, 1, NULL);  // Set conumser Semaphore to Signalled with number of items currently on the queue
        }
+2  A: 

In your worker function, you're storing the pointed-to item, rather than the shared pointer, so the shared-pointer's reference count is not incremented.

Oli Charlesworth
A: 

I guess item is wrong in this case. As the operator returns a reference to your type. So you put a const ref into your list but not a copy of the shared_ptr.

mkaes
+4  A: 
l->push_front(*item);  //Add to list 

The dereference could be the problem. You are not passing a shred_ptr instance to the l list but the pointee itself. If that's not it, please post more complete and less confused test-case.

wilx
+3  A: 

If BaseHookQueueList is an intrusive list like you said, then you should remember that intrusive list doesn't take the ownership of the objects. In this case your shared pointers have the ownership, and when they are destroyed, the object is destroyed too.

edit: Instead of intrusive list you could use a container like std::list or std::queue that can contain smart pointers.

Timo
but std::list makes a copy of the object when you put it in the list, won't that create a lot of overhead if you have lots of objects in the list???
Tony
If your list contains `shared_ptr` the cost would be that of copying the shared pointer, which is *small* (copy of a couple of pointers and update of the reference count)
David Rodríguez - dribeas
@David: small, but does trigger a few dereferences + access to a shared resource (the counter). It is lessened if the `shared_ptr` has been created by `make_shared`.
Matthieu M.