1

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)

2
  • Try allocating your ThreadInfo with a plain old new instead of IMemoryAllocator and see if the exceptions go away. Commented Aug 31, 2012 at 20:09
  • @ecatmur: No, it's exception::what ;-P Commented Aug 31, 2012 at 20:13

1 Answer 1

5

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.

Sign up to request clarification or add additional context in comments.

2 Comments

@KaiserJohaan: Note that before deallocating, you should also call the destructor: mThreadInfo->~ThreadInfo(). Also the above code is not exception safe, i.e. if ThreadInfo constructor throws an exception then you should deallocate the memory without calling the destructor.
And all this illustrates how the low-level stuff is hard, and why you should use existing high-level libraries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.