I didn't look really close at your example, but here's what I do. It's
pretty simple:

// Reusable class
class CLockWhileExists
{
public:
        explicit CLockWhileExists(CCriticalSection& critCriticalSection)
                m_critCriticalSection(critCriticalSection)
        {
                critCriticalSection.Lock();
        }

        ~CLockWhileExists()
        {
                m_critCriticalSection.Unlock();
        }
private:
        CCriticalSection& m_critCriticalSection;
};

// Your particular code
class CThreadSafeClass
{
private:
        CCriticalSection m_critLock;
...
};

void CThreadSafeClass::Something()
{
        if (...)
        {
                CLockWhileExists lwe(m_critCriticalSection);
                // Everything is thread safe until the closing brace.
        }       // This implicitly unlocks the critical section.
}

void CThreadSafeClass::SomethingElse()
{
        CLockWhileExists lwe(m_critCriticalSection);
        // Everything is thread safe until the closing brace.
}

Note that the parameter I put into CLockWhileExists is the same. If you
want to create two different protections, just declare another
CCriticalSection. CCriticalSection is a member variable so that the same
one is used by any function that needs that type of protection.

> -----Original Message-----
> From: [EMAIL PROTECTED] 
> [mailto:[EMAIL PROTECTED] On Behalf Of Jason Teagle
> Sent: Friday, April 09, 2004 10:47 AM
> To: MSVC At BeginThread
> Subject: [msvc] Critical Sections... How?
> 
> 
> I'm trying to use a CCriticalSection, but failing. I get 
> access violations
> when I try to lock. So I'm clearly doing it wrong.
> 
> Here's the scenario:
> 
> Class A creates a worker thread.
> Class A wants to queue up items for the worker thread to 
> handle one at a
> time. These items can be represented by a single UINT.
> 
> Thus, I believe I am correct in saying that I should be using 
> a critical
> section to control putting things into the queue and pulling 
> things out of
> the queue, so they don't clash. (Clearly I've never used a sync object
> before).
> 
> For now, I was trying to use a CUIntArray as the queue itself 
> (probably not
> the most efficient, but I just want to get it working first 
> before I worry
> about efficiency - but I'm open to better suggestions of MFC (not ATL,
> sorry) objects to use for a queue).
> 
> But, this array is a member of a structure declared globally:
> 
> (Header file)
> typedef struct tagItemQueue
> {
>       BOOL            bTerminate ;
>       CUIntArray      aryItems ;
> 
> } ITEM_QUEUE ;
> 
> (Implementation file)
> static const g_sItemQueue ;
> 
> This is passed (by its pointer) as the user parameter to the 
> worker thread
> on creation (I could use the global reference, but chose not 
> to). The worker
> thread then tries to access it.
> 
> This all seems to work fine.
> 
> 
> 
> So now I tried adding a critical section, by updating the structure:
> 
> typedef struct tagXXX
> {
>       BOOL                    bTerminate ;
>       CUIntArray              aryItems ;
>       CCriticalSection                CriticalSection ;
> 
> } XXX ;
> 
> 
> Accordingly, in the thread (and where it tries to add things 
> to the queue),
> I try:
> 
> if (psQueue->CriticalSection.Lock(1000) )
> {
>       // Do something thread-safely...
> 
>       psQueue->Unlock();
> }
> 
> 
> But when I run the program, it access violates at the .Lock() line.
> 
> Have I done something wrong? This is the best I can make out 
> from MSDN on
> CCriticalSection (I tried using a CSingleLock in conjunction 
> with it, but
> that failed too, although for different reasons that I can't 
> fathom - so I
> used the critical section directly, as MSDN says I can).
> 
> --
> Jason Teagle
> [EMAIL PROTECTED]
> 
> 
> 
> _______________________________________________
> msvc mailing list
> [EMAIL PROTECTED]
> See 
> http://beginthread.com/mailman/listinfo/msvc_b> eginthread.com 
> for subscription changes, and list archive.
> 



Reply via email to