fogbit
fogbit

Reputation: 2063

WaitForSingleObject crashes

Here is a code below. The code is not complete, I omitted releasing resources part and implementation of QueryRes logic.

#define N 5

/*simply resources manager which has N shared resources*/
class ResourceManager
{
public:
    ResourceManager()
    {
            for (int i = 0; i < N; ++i)
              resources[i] = CreateMutex(NULL, FALSE, NULL);
    }
/*CreateMutex for on resources array in ctor*/
/*CloseHandle() in dtor and ReleaseMutex in another function which is called after QueryRes*/

        void QueryRes(int i)
        {
          WaitForSingleObject(resources[i], INFINITE); //(*) Here is the problem
        }

private:
        HANDLE resources[N];
};

/*User who asks for resource time-to-time*/
class User
{
public:
    User(ResourceManager& res_holder_, int res_num) : resource_holder(resource_holder), resource_to_query(res_num) {}

    void WorkWithResource()
    {
            while(1)
            {
                    resource_holder.QueryRes(resource_to_query);
            }
    }


    static void Run (void* params)
    {
            static_cast<User*>(params)->WorkWithResource();
    }

private:
    ResourceManager& resource_holder;
    int resource_to_query;
};

int main()
{
        ResourceManager resource_manager;
        User* users[5];
        HANDLE threads[5];

        for (size_t i = 0 ; i < 5; ++i)
        {
                users[i] = new User(resource_manager, i % 5);
                threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)&User::Run, users[i], 0, NULL);
        }
        WaitForMultipleObjects(5, threads, true, INFINITE);


        return 0;
}

At (*) place I get an "access violation exception" when the function does WaitForSingleObject on already locked mutex.

I also tried

 while(WaitForSingleObject(resources[i], INFINITE) != WAIT_OBJECT_0) 

and got the same result.

Why do I get the exception?

I tried vc 2003, 2008 and 2010. I can't use boost/pthreads/etc.

Thank you.

Upvotes: 0

Views: 4198

Answers (2)

Thierry Franzetti
Thierry Franzetti

Reputation: 1863

The error lies in the constructor of

User(ResourceManager& res_holder_, int res_num) : resource_holder(resource_holder), resource_to_query(res_num)    {   }

You should have

User(ResourceManager& res_holder_, int res_num) : resource_holder(**res_holder_**), resource_to_query(res_num)    {   }

instead !

Upvotes: 4

asveikau
asveikau

Reputation: 40284

When you get an access violation (or segfault in other platforms, although generically speaking this is a bad pointer dereference), often the reason is obvious from looking at the code... In this case nothing pops out at me from what you've posted. My guess based on what you said is something smashed the stack.

However, a bit of advice... When you see an access violation you can't explain, the first step is not to post to Stack Overflow. Look at it in a debugger! If you download "Debugging tools for Windows" from Microsoft and use "windbg", and learn how to use it, it will tell you more about this crash than you ever thought you could know - what the bad address it tried to access was, disassembly of WaitForMultipleObjects so you can see what it's doing and where the address came from, etc. I usually find with a few k, r, u, and dq commands in windbg, the cause for a bad pointer dereference becomes pretty obvious.

Upvotes: 1

Related Questions