/*
   Copyright (c) 2011 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 <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);
#ifdef WINPTHREAD_DBG
    assert((((rwlock_t *)*rwl)->valid == LIFE_RWLOCK) && (((rwlock_t *)*rwl)->busy > 0));
#endif
     ((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;
    INIT_RWLOCK(rwl);
    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 = NULL;
    pthread_spin_lock(&rwl_global);
    
    if (!rwl || !*rwl) r = EINVAL;
    else {
        rwlock_t *r_ = (rwlock_t *)*rwl;
        if (STATIC_RWL_INITIALIZER(*rwl)) *rwl = NULL;
        else if (r_->valid != LIFE_RWLOCK) r = EINVAL;
        else if (r_->busy) r = EBUSY;
        else {
            *rDestroy = *rwl;
            *rwl = 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;
}

#ifdef WINPTHREAD_DBG
static int print_state = 0;
void rwl_print_set(int state)
{
    print_state = state;
}

void rwl_print(volatile pthread_rwlock_t *rwl, char *txt)
{
    if (!print_state) return;
    rwlock_t *r = (rwlock_t *)*rwl;
    if (r == NULL) {
        printf("RWL%p %d %s\n",*rwl,(int)GetCurrentThreadId(),txt);
    } else {
        printf("RWL%p %d V=%0X B=%d r=%ld w=%ld L=%p %s\n",
            *rwl, 
            (int)GetCurrentThreadId(), 
            (int)r->valid, 
            (int)r->busy,
            0L,0L,NULL,txt);
    }
}
#endif

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_ = NULL;
    if ((rwlock = (pthread_rwlock_t)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_ = 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(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;
}
