/**********************************************************************
 * Copyright (c) 2005, 2007 IBM Corporation and others.
 * All rights reserved.   This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 * $Id: lock3.h,v 1.2 2007/04/06 00:07:51 jkubasta Exp $
 * 
 * Contributors: 
 * IBM - Initial API and implementation
 **********************************************************************/

#ifndef _LOCK3_H_
#define _LOCK3_H_


#ifdef _WIN32
#include <winsock2.h> /* Bug 134924 */
#include <windows.h>

// The single-writer/multiple-reader guard
// compound synchronization object
typedef struct _SWMR {
   // This critical section guards access to the other objects
   // managed by this data structure and also indicates
   // whether any writer threads are writing.
   CRITICAL_SECTION cs;

   // This manual-reset event is signaled when
   // no reader threads are reading.
   HANDLE hEventNoReaders;

   LONG numReaders;
} Lock_t;



#else
  #include <pthread.h>
  #include "RAComm.h"

#if defined __linux__ || defined _HPUX
  typedef struct {
    pthread_mutex_t mutex;
    pthread_cond_t  rcond;
    pthread_cond_t  wcond;
    long readCount;
    short waiting_writers;
    short active_writers;
  } Lock_t;
  extern void rwlock_WaitingReaderCleanup(void *arg);
  extern void rwlock_WaitingWriterCleanup(void *arg);
#else
  typedef pthread_rwlock_t Lock_t;
#endif

#endif


#if defined __cplusplus && defined _HPUX
extern "C" {
#endif

/** Initializes a SWMRG structure. This structure must be
	initialized before any writer or reader threads attempt
	to wait on it.
	The structure must be allocated by the application and
	the structure's address is passed as the first parameter.
	The lpszName parameter is the name of the object. Pass
	NULL if you do not want to share the object.
  */
extern BOOL  ra_initializeLock (Lock_t *lock);


/** Deletes the system resources associated with a SWMRG
	structure. The structure must be deleted only when
	no writer or reader threads in the calling process
	will wait on it.
  */
extern void ra_deleteLock (Lock_t *lock);

/** A writer thread calls this function to know when
	it can successfully write to the shared data.
  */
extern int ra_getWriteLock (Lock_t *lock);


/** A writer thread calls this function to let other threads
	know that it no longer needs to write to the shared data.
  */
extern void ra_releaseWriteLock (Lock_t *lock);


/** A reader thread calls this function to know when
	it can successfully read the shared data.
  */
extern int ra_getReadLock(Lock_t *lock);


/** A reader thread calls this function to let other threads
	know when it no longer needs to read the shared data.
  */
extern void ra_releaseReadLock (Lock_t *lock);

#if defined __cplusplus && defined _HPUX
}
#endif

#endif
