So here is my latest project. It is pretty complex what with all the synchronization. Hopefully I've commented it enough for you to get the gist out of it works.
I'm sure there are probably tons of little small problems. Feel free to point them out.
Possibly there are bugs as well, so again feel free to point out how you would have done it.

The code is below. I'm also attaching the files if someone finds that more convenient.

//Wake up any waiting threads.
//Always do this, even if count_ wasn't 0 on entry.
//Otherwise, we might not wake up enough waiting threads if we
//get a number of signal() calls in a row.
m_condition.notify_one();
}

tbb::atomic<unsigned int> g_NumFemalesChanging, g_NumMalesChanging; // Keeps track of number females/males currently dressing. We need to keep track of the last one leaving the dressing room.
tbb::atomic<unsigned int> g_NumFemalesWaiting, g_NumMalesWaiting; // Keeps track of number females/males currently waiting to dress. We need to keep track of the first one to wait.

// Starts up a timer to ensure one gender does not keep hugging the dressing room to themselves.
// If the timer expires and the same gender is occupying the room as before, it will kick them out of there.
class XTimer
{
protected:
boost::thread m_TimerThread;

void EnterDressingRoom(bool IsFemale, int id, int thread_id)
{
try
{
std::string WordCapitalMaleFemale /* contains "Male" or "Female" */, WordOppositeMaleFemale /* contains "female" or "male" */, WordHeShe; /* contains "he" or "she" */
XEvent* GenderEvent; // Signals when there are no more of the current gender changing
XEvent* OppositeEvent; // Signals when there are no more of the OPPOSITE gender changing
tbb::atomic<unsigned int>* GenderChangingCount; // Counts the number of the current gender changing. Used to know when the first of the gender enters and leaves the dressing room.
tbb::atomic<unsigned int>* GenderWaitingCount; // Counts the number of the current gender changing. Used to know when the first of the gender enters and leaves the dressing room.
XEvent* GenderOKToChange;
XEvent* OppositeOKToChange;

// Give timer thread OK to start. This is to ensure that we do not wait forever. If one gender takes too long to change, and there is a queue with the opposite gender, then we must clear
// the currently changing ender so the other gender can start changing.
if (++*GenderWaitingCount == 1)
{
XTimer timer(!IsFemale); // Constructor expects the gender who is currently changing
g_TurnLock.up(); // We MUST release the lock to allow other threads to process here.
OppositeEvent->wait(); // Wait until opposite gender has stopped changing
}
else
{
g_TurnLock.up(); // We MUST release the lock to allow other threads to process here.
OppositeEvent->wait(); // Wait until opposite gender has stopped changing
}

if (++(*GenderChangingCount) == 1) // Increase the count of current number of individuals in dressing room. We need to keep track of the last one leaving.
{
OppositeOKToChange->signal();
GenderEvent->clear(); // Clear the signal that the current gender isn't changing (they will change now!)
}

NO_INTERRUPTS // Again, we must disable interrupts because it can leave the function in an inconsistent state.
g_ThreadData.container[thread_id].Changing = false;
if (--(*GenderChangingCount) == 0)
GenderEvent->signal(); // Signal that none of the current gender changing is now changing