t***@gmail.com
2016-03-04 04:33:02 UTC
So you'd like to modify it so that if there a writer requests access, that
no new readers can be admitted until the writer has been allowed in
and out? Well, you have the code, how would you fix the sharedread_sem
structure and the various lock procedures? New readers would be
treated somewhat like writers, wouldn't they, with a loop? Can you write
the code?
I've taken a stab at it...no new readers can be admitted until the writer has been allowed in
and out? Well, you have the code, how would you fix the sharedread_sem
structure and the various lock procedures? New readers would be
treated somewhat like writers, wouldn't they, with a loop? Can you write
the code?
The issue, it seems to me, is that you want to prevent new readers when
there's a pending write. So, it seems to call for another critical
typedef struct sh {
CRITICAL_SECTION lock;
CRITICAL_SECTION readlock;
HANDLE writelock; /* Manual-reset event */
int readers;
} sharedread_sem;
void initialize( sharedread_sem *s )
{
InitializeCriticalSection(&s->lock);
InitializeCriticalSection(&s->readlock);
s->readers = 0;
s->writelock = CreateEvent(NULL, TRUE,
FALSE, NULL);
}
void write_lock( sharedread_sem *s )
{
EnterCriticalSection(&s->readlock);
EnterCriticalSection(&s->lock);
if (s->readers)
{
LeaveCriticalSection(&s->lock);
WaitForSingleObject(s->writelock, INFINITE);
goto top;
}
LeaveCriticalSection(&s->readlock);
}
void release_write_lock( sharedread_sem *s )
{
LeaveCriticalSection(&s->lock);
}
void read_lock( sharedread_sem *s )
{
EnterCriticalSection(&s->readlock);
EnterCriticalSection(&s->lock);
s->readers++;
ResetEvent(s->writelock);
LeaveCriticalSection(&s->lock);
LeaveCriticalSection(&s->readlock);
}
void release_read_lock( sharedread_sem *s )
{
EnterCriticalSection(&s->lock);
if (--s->readers == 0)
SetEvent(s->writelock);
LeaveCriticalSection(&s->lock);
}
--
Jordan Zimmerman
Altura Software, Inc.
Catalog City, Inc. http://www.catalogcity.com
http://www.moraldefense.com/microsoft
After applying your modification (see above) it is no longer absolutely necessary to use the "goto" statement in function write_lock(). That is, now that writers are guaranteed a fair go, we should be able to define function write_lock() as:
void write_lock( sharedread_sem *s )
{
EnterCriticalSection(&s->readlock);
EnterCriticalSection(&s->lock);
if (s->readers)
{
LeaveCriticalSection(&s->lock);
WaitForSingleObject(s->writelock, INFINITE);
}
LeaveCriticalSection(&s->readlock);
}
This is because not only does the call to EnterCriticalSection(&s->readlock) serialize calls by multiple writers, it also prevents any readers from subsequently incrementing s->readers while any writer holds the critical section s->readlock. When a writer returns from the call to WaitForSingleObject(s->writelock, INFINITE) in function write_lock(), then s->readers is guaranteed to be 0 so long as the writer holds the critical section s->readlock.
Thanks in advance.