Question

Boost::function is throwing me exceptions one out of ten times when I try to assign one function1 to another function1.

Task is a typedef for boost::function1<void, void*>.

Here is the specific code:

    // the Task object sent in as Task task
    void Sleeper(void* arg)
    {
        int32_t sleepTime = *(int32_t*)arg;

        SleepCurrentThread((int32_t)sleepTime);
    }

    struct ThreadInfo
    {
        ThreadInfo() : mState(DETACHED), mTask(NULL), mArg(NULL)
        { }

        ThreadState mState;
        Task mTask;
        void* mArg;
    };

    Thread::Thread(Task task, void* arg, IMemoryAllocator& allocator, ILogManager& logger) : mAllocator(allocator), mLogger(logger)
    {
        mThreadInfo = (ThreadInfo*) mAllocator.Allocate(sizeof(ThreadInfo));  // simnple heap allocation

        mThreadInfo->mArg = arg;
        mThreadInfo->mState = Thread::RUNNING;
        mThreadInfo->mTask = task;     //<--------- throws... sometimes


        mHandle = _CreateThread(&Run, (void*)mThreadInfo);
        if (!mHandle)
            Detach();


    }

I specificly tracked it down in the boost function_template.hpp to the assignment operator, on this code, where it ultimately throws:

// Assignment from another BOOST_FUNCTION_FUNCTION
    BOOST_FUNCTION_FUNCTION& operator=(const BOOST_FUNCTION_FUNCTION& f)
    {
      if (&f == this)
        return *this;

      this->clear();
      BOOST_TRY {
        this->assign_to_own(f);        // <--- throws, and then line below re-throws
      } BOOST_CATCH (...) {
        vtable = 0;
        BOOST_RETHROW;
      }
      BOOST_CATCH_END
      return *this;
    }

Why is this? Is there anything easily spotted that is wrong with my code? Is there anything else needed?

Thanks

EDIT: I know I will be asked to use boost::threads, but I'm trying out my own wrapper around win32/pthread, (for fun)

Was it helpful?

Solution

Your struct has a non-trivial constructor, but you don't call it. It leaves the Task member uninitialized. To initialize it, either allocate the whole object with new, or use placement new to initialize it as follows:

    void *mem = mAllocator.Allocate(sizeof(ThreadInfo));  // simnple heap allocation
    mThreadInfo = new(mem) ThreadInfo; // placement new

    mThreadInfo->mArg = arg;
    mThreadInfo->mState = Thread::RUNNING;
    mThreadInfo->mTask = task;

Placement new constructs an object in an already allocated raw (uninitialized) memory.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top