/*
   Copyright (c) 2011-2016  mingw-w64 project

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included in
   all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

#ifdef HAVE_CONFIG_H
#include "config.h"
#endif

#include <assert.h>
#include <malloc.h>
#include <stdio.h>

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

#define WINPTHREAD_RWLOCK_DECL WINPTHREAD_API

/* public header files */
#include "pthread.h"
/* internal header files */
#include "misc.h"
#include "rwlock.h"
#include "thread.h"

static pthread_spinlock_t rwl_global = PTHREAD_SPINLOCK_INITIALIZER;

static WINPTHREADS_ATTRIBUTE((noinline)) int rwlock_static_init(pthread_rwlock_t *rw);

static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_unref(volatile pthread_rwlock_t *rwl, int res)
{
    pthread_spin_lock(&rwl_global);
    assert((((rwlock_t *)*rwl)->valid == LIFE_RWLOCK) && (((rwlock_t *)*rwl)->busy > 0));
     ((rwlock_t *)*rwl)->busy--;
    pthread_spin_unlock(&rwl_global);
    return res;
}

static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_ref(pthread_rwlock_t *rwl, int f )
{
    int r = 0;
    if (STATIC_RWL_INITIALIZER(*rwl)) {
        r = rwlock_static_init(rwl);
        if (r != 0 && r != EBUSY)
            return r;
    }
    pthread_spin_lock(&rwl_global);

    if (!rwl || !*rwl || ((rwlock_t *)*rwl)->valid != LIFE_RWLOCK) r = EINVAL;
    else {
        ((rwlock_t *)*rwl)->busy ++;
    }

    pthread_spin_unlock(&rwl_global);

    return r;
}

static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_ref_unlock(pthread_rwlock_t *rwl )
{
    int r = 0;

    pthread_spin_lock(&rwl_global);

    if (!rwl || !*rwl || ((rwlock_t *)*rwl)->valid != LIFE_RWLOCK) r = EINVAL;
    else if (STATIC_RWL_INITIALIZER(*rwl)) r= EPERM;
    else {
        ((rwlock_t *)*rwl)->busy ++;
    }

    pthread_spin_unlock(&rwl_global);

    return r;
}

static WINPTHREADS_ATTRIBUTE((noinline)) int rwl_ref_destroy(pthread_rwlock_t *rwl, pthread_rwlock_t *rDestroy )
{
    int r = 0;

    *rDestroy = (pthread_rwlock_t)NULL;
    pthread_spin_lock(&rwl_global);

    if (!rwl || !*rwl) r = EINVAL;
    else {
        rwlock_t *r_ = (rwlock_t *)*rwl;
        if (STATIC_RWL_INITIALIZER(*rwl)) *rwl = (pthread_rwlock_t)NULL;
        else if (r_->valid != LIFE_RWLOCK) r = EINVAL;
        else if (r_->busy) r = EBUSY;
        else {
            *rDestroy = *rwl;
            *rwl = (pthread_rwlock_t)NULL;
        }
    }

    pthread_spin_unlock(&rwl_global);
    return r;
}

static int rwlock_gain_both_locks(rwlock_t *rwlock)
{
  int ret;
  ret = pthread_mutex_lock(&rwlock->mex);
  if (ret != 0)
    return ret;
  ret = pthread_mutex_lock(&rwlock->mcomplete);
  if (ret != 0)
    pthread_mutex_unlock(&rwlock->mex);
  return ret;
}

static int rwlock_free_both_locks(rwlock_t *rwlock, int last_fail)
{
  int ret, ret2;
  ret = pthread_mutex_unlock(&rwlock->mcomplete);
  ret2 = pthread_mutex_unlock(&rwlock->mex);
  if (last_fail && ret2 != 0)
    ret = ret2;
  else if (!last_fail && !ret)
    ret = ret2;
  return ret;
}

static pthread_spinlock_t cond_locked = PTHREAD_SPINLOCK_INITIALIZER;

static WINPTHREADS_ATTRIBUTE((noinline)) int rwlock_static_init(pthread_rwlock_t *rw)
{
  int r;
  pthread_spin_lock(&cond_locked);
  if (*rw != PTHREAD_RWLOCK_INITIALIZER)
  {
    pthread_spin_unlock(&cond_locked);
    return EINVAL;
  }
  r = pthread_rwlock_init (rw, NULL);
  pthread_spin_unlock(&cond_locked);

  return r;
}

int pthread_rwlock_init (pthread_rwlock_t *rwlock_, const pthread_rwlockattr_t *attr)
{
    rwlock_t *rwlock;
    int r;

    if(!rwlock_)
      return EINVAL;
    *rwlock_ = (pthread_rwlock_t)NULL;
    if ((rwlock = calloc(1, sizeof(*rwlock))) == NULL)
      return ENOMEM;
    rwlock->valid = DEAD_RWLOCK;

    rwlock->nex_count = rwlock->nsh_count = rwlock->ncomplete = 0;
    if ((r = pthread_mutex_init (&rwlock->mex, NULL)) != 0)
    {
        free(rwlock);
        return r;
    }
    if ((r = pthread_mutex_init (&rwlock->mcomplete, NULL)) != 0)
    {
      pthread_mutex_destroy(&rwlock->mex);
      free(rwlock);
      return r;
    }
    if ((r = pthread_cond_init (&rwlock->ccomplete, NULL)) != 0)
    {
      pthread_mutex_destroy(&rwlock->mex);
      pthread_mutex_destroy (&rwlock->mcomplete);
      free(rwlock);
      return r;
    }
    rwlock->valid = LIFE_RWLOCK;
    *rwlock_ = (pthread_rwlock_t)rwlock;
    return r;
}

int pthread_rwlock_destroy (pthread_rwlock_t *rwlock_)
{
    rwlock_t *rwlock;
    pthread_rwlock_t rDestroy;
    int r, r2;

    pthread_spin_lock(&cond_locked);
    r = rwl_ref_destroy(rwlock_,&rDestroy);
    pthread_spin_unlock(&cond_locked);

    if(r) return r;
    if(!rDestroy) return 0; /* destroyed a (still) static initialized rwl */

    rwlock = (rwlock_t *)rDestroy;
    r = rwlock_gain_both_locks (rwlock);
    if (r != 0)
    {
      *rwlock_ = rDestroy;
      return r;
    }
    if (rwlock->nsh_count > rwlock->ncomplete || rwlock->nex_count > 0)
    {
      *rwlock_ = rDestroy;
      r = rwlock_free_both_locks(rwlock, 1);
      if (!r)
        r = EBUSY;
      return r;
    }
    rwlock->valid  = DEAD_RWLOCK;
    r = rwlock_free_both_locks(rwlock, 0);
    if (r != 0) { *rwlock_ = rDestroy; return r; }

    r = pthread_cond_destroy(&rwlock->ccomplete);
    r2 = pthread_mutex_destroy(&rwlock->mex);
    if (!r) r = r2;
    r2 = pthread_mutex_destroy(&rwlock->mcomplete);
    if (!r) r = r2;
    rwlock->valid  = DEAD_RWLOCK;
    free((void *)rDestroy);
    return 0;
}

int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock_)
{
  rwlock_t *rwlock;
  int ret;

  /* pthread_testcancel(); */

  ret = rwl_ref(rwlock_,0);
  if(ret != 0) return ret;

  rwlock = (rwlock_t *)*rwlock_;

  ret = pthread_mutex_lock(&rwlock->mex);
  if (ret != 0) return rwl_unref(rwlock_, ret);
  InterlockedIncrement((long*)&rwlock->nsh_count);
  if (rwlock->nsh_count == INT_MAX)
  {
    ret = pthread_mutex_lock(&rwlock->mcomplete);
    if (ret != 0)
    {
      pthread_mutex_unlock(&rwlock->mex);
      return rwl_unref(rwlock_,ret);
    }
    rwlock->nsh_count -= rwlock->ncomplete;
    rwlock->ncomplete = 0;
    ret = rwlock_free_both_locks(rwlock, 0);
    return rwl_unref(rwlock_, ret);
  }
  ret = pthread_mutex_unlock(&rwlock->mex);
  return rwl_unref(rwlock_, ret);
}

/* Internal version which always uses `struct _timespec64`. */
static int __pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct _timespec64 *ts)
{
  rwlock_t *rwlock;
  int ret;

  /* pthread_testcancel(); */

  ret = rwl_ref(rwlock_,0);
  if(ret != 0) return ret;

  rwlock = (rwlock_t *)*rwlock_;
  if ((ret = pthread_mutex_timedlock64 (&rwlock->mex, ts)) != 0)
      return rwl_unref(rwlock_, ret);
  InterlockedIncrement(&rwlock->nsh_count);
  if (rwlock->nsh_count == INT_MAX)
  {
    ret = pthread_mutex_timedlock64(&rwlock->mcomplete, ts);
    if (ret != 0)
    {
      if (ret == ETIMEDOUT)
	InterlockedIncrement(&rwlock->ncomplete);
      pthread_mutex_unlock(&rwlock->mex);
      return rwl_unref(rwlock_, ret);
    }
    rwlock->nsh_count -= rwlock->ncomplete;
    rwlock->ncomplete = 0;
    ret = rwlock_free_both_locks(rwlock, 0);
    return rwl_unref(rwlock_, ret);
  }
  ret = pthread_mutex_unlock(&rwlock->mex);
  return rwl_unref(rwlock_, ret);
}

int pthread_rwlock_timedrdlock64(pthread_rwlock_t *l, const struct _timespec64 *ts)
{
  return __pthread_rwlock_timedrdlock (l, ts);
}

int pthread_rwlock_timedrdlock32(pthread_rwlock_t *l, const struct _timespec32 *ts)
{
  struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec};
  return __pthread_rwlock_timedrdlock (l, &ts64);
}

int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock_)
{
  rwlock_t *rwlock;
  int ret;

  ret = rwl_ref(rwlock_,RWL_TRY);
  if(ret != 0) return ret;

  rwlock = (rwlock_t *)*rwlock_;
  ret = pthread_mutex_trylock(&rwlock->mex);
  if (ret != 0)
      return rwl_unref(rwlock_, ret);
  InterlockedIncrement(&rwlock->nsh_count);
  if (rwlock->nsh_count == INT_MAX)
  {
    ret = pthread_mutex_lock(&rwlock->mcomplete);
    if (ret != 0)
    {
      pthread_mutex_unlock(&rwlock->mex);
      return rwl_unref(rwlock_, ret);
    }
    rwlock->nsh_count -= rwlock->ncomplete;
    rwlock->ncomplete = 0;
    ret = rwlock_free_both_locks(rwlock, 0);
    return rwl_unref(rwlock_, ret);
  }
  ret = pthread_mutex_unlock(&rwlock->mex);
  return rwl_unref(rwlock_,ret);
}

int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock_)
{
  rwlock_t *rwlock;
  int ret;

  ret = rwl_ref(rwlock_,RWL_TRY);
  if(ret != 0) return ret;

  rwlock = (rwlock_t *)*rwlock_;
  ret = pthread_mutex_trylock (&rwlock->mex);
  if (ret != 0)
    return rwl_unref(rwlock_, ret);
  ret = pthread_mutex_trylock(&rwlock->mcomplete);
  if (ret != 0)
  {
    int r1 = pthread_mutex_unlock(&rwlock->mex);
    if (r1 != 0)
      ret = r1;
    return rwl_unref(rwlock_, ret);
  }
  if (rwlock->nex_count != 0)
    return rwl_unref(rwlock_, EBUSY);
  if (rwlock->ncomplete > 0)
  {
    rwlock->nsh_count -= rwlock->ncomplete;
    rwlock->ncomplete = 0;
  }
  if (rwlock->nsh_count > 0)
  {
    ret = rwlock_free_both_locks(rwlock, 0);
    if (!ret)
      ret = EBUSY;
    return rwl_unref(rwlock_, ret);
  }
  rwlock->nex_count = 1;
  return rwl_unref(rwlock_, 0);
}

int pthread_rwlock_unlock (pthread_rwlock_t *rwlock_)
{
  rwlock_t *rwlock;
  int ret;

  ret = rwl_ref_unlock(rwlock_);
  if(ret != 0) return ret;

  rwlock = (rwlock_t *)*rwlock_;
  if (rwlock->nex_count == 0)
  {
    ret = pthread_mutex_lock(&rwlock->mcomplete);
    if (!ret)
    {
      int r1;
      InterlockedIncrement(&rwlock->ncomplete);
      if (rwlock->ncomplete == 0)
	ret = pthread_cond_signal(&rwlock->ccomplete);
      r1 = pthread_mutex_unlock(&rwlock->mcomplete);
      if (!ret)
	ret = r1;
    }
  }
  else
  {
    InterlockedDecrement(&rwlock->nex_count);
    ret = rwlock_free_both_locks(rwlock, 0);
  }
  return rwl_unref(rwlock_, ret);
}

static void st_cancelwrite (void *arg)
{
    rwlock_t *rwlock = (rwlock_t *)arg;

    rwlock->nsh_count = - rwlock->ncomplete;
    rwlock->ncomplete = 0;
    rwlock_free_both_locks(rwlock, 0);
}

int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock_)
{
  rwlock_t *rwlock;
  int ret;

  /* pthread_testcancel(); */
  ret = rwl_ref(rwlock_,0);
  if(ret != 0) return ret;

  rwlock = (rwlock_t *)*rwlock_;
  ret = rwlock_gain_both_locks(rwlock);
  if (ret != 0)
    return rwl_unref(rwlock_,ret);

  if (rwlock->nex_count == 0)
  {
    if (rwlock->ncomplete > 0)
    {
      rwlock->nsh_count -= rwlock->ncomplete;
      rwlock->ncomplete = 0;
    }
    if (rwlock->nsh_count > 0)
    {
      rwlock->ncomplete = -rwlock->nsh_count;
      pthread_cleanup_push(st_cancelwrite, (void *) rwlock);
      do {
	ret = pthread_cond_wait(&rwlock->ccomplete, &rwlock->mcomplete);
      } while (!ret && rwlock->ncomplete < 0);

      pthread_cleanup_pop(!ret ? 0 : 1);
      if (!ret)
	rwlock->nsh_count = 0;
    }
  }
  if(!ret)
    InterlockedIncrement((long*)&rwlock->nex_count);
  return rwl_unref(rwlock_,ret);
}

/* Internal version which always uses `struct _timespec64`. */
static int __pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct _timespec64 *ts)
{
  int ret;
  rwlock_t *rwlock;

  /* pthread_testcancel(); */
  if (!rwlock_ || !ts)
    return EINVAL;
  if ((ret = rwl_ref(rwlock_,0)) != 0)
    return ret;
  rwlock = (rwlock_t *)*rwlock_;

  ret = pthread_mutex_timedlock64(&rwlock->mex, ts);
  if (ret != 0)
    return rwl_unref(rwlock_,ret);
  ret = pthread_mutex_timedlock64(&rwlock->mcomplete, ts);
  if (ret != 0)
  {
    pthread_mutex_unlock(&rwlock->mex);
    return rwl_unref(rwlock_,ret);
  }
  if (rwlock->nex_count == 0)
  {
    if (rwlock->ncomplete > 0)
    {
      rwlock->nsh_count -= rwlock->ncomplete;
      rwlock->ncomplete = 0;
    }
    if (rwlock->nsh_count > 0)
    {
      rwlock->ncomplete = -rwlock->nsh_count;
      pthread_cleanup_push(st_cancelwrite, (void *) rwlock);
      do {
	ret = pthread_cond_timedwait64(&rwlock->ccomplete, &rwlock->mcomplete, ts);
      } while (rwlock->ncomplete < 0 && !ret);
      pthread_cleanup_pop(!ret ? 0 : 1);

      if (!ret)
	rwlock->nsh_count = 0;
    }
  }
  if(!ret)
    InterlockedIncrement((long*)&rwlock->nex_count);
  return rwl_unref(rwlock_,ret);
}

int pthread_rwlock_timedwrlock64(pthread_rwlock_t *rwlock, const struct _timespec64 *ts)
{
  return __pthread_rwlock_timedwrlock (rwlock, ts);
}

int pthread_rwlock_timedwrlock32(pthread_rwlock_t *rwlock, const struct _timespec32 *ts)
{
  struct _timespec64 ts64 = {.tv_sec = ts->tv_sec, .tv_nsec = ts->tv_nsec};
  return __pthread_rwlock_timedwrlock (rwlock, &ts64);
}

int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
{
  if (!a)
    return EINVAL;
  return 0;
}

int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
{
  if (!a)
    return EINVAL;
  *a = PTHREAD_PROCESS_PRIVATE;
  return 0;
}

int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s)
{
  if (!a || !s)
    return EINVAL;
  *s = *a;
  return 0;
}

int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s)
{
  if (!a || (s != PTHREAD_PROCESS_SHARED && s != PTHREAD_PROCESS_PRIVATE))
    return EINVAL;
  *a = s;
  return 0;
}
