/*
   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.
*/

#include <assert.h>
#include <windows.h>
#include <stdio.h>
#include <malloc.h>
#include "pthread.h"
#include "thread.h"
#include "ref.h"
#include "rwlock.h"
#include "misc.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);
}

int pthread_rwlock_timedrdlock (pthread_rwlock_t *rwlock_, const struct timespec *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_timedlock (&rwlock->mex, ts)) != 0)
      return rwl_unref(rwlock_, ret);
  InterlockedIncrement(&rwlock->nsh_count);
  if (rwlock->nsh_count == INT_MAX)
  {
    ret = pthread_mutex_timedlock(&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_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);
}

int pthread_rwlock_timedwrlock (pthread_rwlock_t *rwlock_, const struct timespec *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_timedlock(&rwlock->mex, ts);
  if (ret != 0)
    return rwl_unref(rwlock_,ret);
  ret = pthread_mutex_timedlock (&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_timedwait(&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_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;
}
