/*
 * Copyright 1999-2000 Sun Microsystems, Inc.  All Rights Reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 *   - Redistributions of source code must retain the above copyright
 *     notice, this list of conditions and the following disclaimer.
 *
 *   - Redistributions in binary form must reproduce the above copyright
 *     notice, this list of conditions and the following disclaimer in the
 *     documentation and/or other materials provided with the distribution.
 *
 *   - Neither the name of Sun Microsystems nor the names of its
 *     contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
 * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

/*
 **********************************************************************
 * Poller.c :
 * JNI code for use with Poller.java, principally to take advantage
 * of poll() or /dev/poll multiplexing.
 *
 * One will need Solaris 8 or Solaris 7 with adequate patches to take
 * advantage of the /dev/poll performance enhancements, though any
 * version of Solaris 7 will automatically use the kernel poll()
 * caching.  And poll() will function in 2.5.1 and 2.6 as well, but
 * will not perform well for large numbers of file descriptors.
 *
 * Several assumptions have been made to simplify this code :
 *  1> At most MAX_HANDLES (32) separate pollable entities are currently
 *     supported.
 *  2> Global synchronization from Java is assumed for all init, create
 *     and destroy routines.  Per Object (handle passed in) synchronization
 *     is required for all AddFd, RemoveFd, IsMember, and Wait routines.
 *  3> It is currently up to the user to handle waking up an
 *     existing nativeWait() call to do an addfd or removefd on
 *     that set...could implement that here with an extra pipe, or
 *     with a pair of loopback sockets in Poller.java or user code.
 *     In most cases interruption is not necessary for deletions,
 *     so long as deletions are queued up outside the Poller class
 *     and then executed the next time waitMultiple() returns.
 *  4> /dev/poll performance could be slightly improved by coalescing
 *     adds/removes so that a write() is only done before the ioctl
 *     (DP_POLL), but this complicates exception handling and sees
 *     only modest performance gains so wasn't done.
 *  5> /dev/poll does not report errors on attempts to remove non-
 *     extant fds, but a future bug fix to the /dev/poll device driver
 *     should solve this problem.
 *  6> Could add simpler code for pre-Solaris 7 releases which will
 *     perform slightly better on those OSs.  But again there
 *     are only modest gains to be had from these new code paths,
 *     so they've been ommitted here.
 *
 * Compile "cc -G -o <dest_dir>/libpoller.so -I ${JAVA_HOME}/include " \
 * -I ${JAVA_HOME}/include/solaris Poller.c" and place the <dest_dir>
 * in your LD_LIBRARY_PATH
 *
 **********************************************************************
 */

#include <stdio.h>
#include <unistd.h>
#include <errno.h>
#include <poll.h>
#include <malloc.h>
#include <fcntl.h>


/*
 * Remove "_NOT"s to turn on features
 * Append "_NOT" to turn off features.
 * Use of /dev/poll requires both the include file and kernel driver.
 */
#define DEBUG_NOT
#define DEVPOLL_NOT

#ifdef DEVPOLL
#include <sys/devpoll.h>
#endif

#include "Poller.h"

#define MAX_HANDLES 32


#ifdef DEBUG
#define DBGMSG(x) printf x
#define ASSERT(x) {if (!(x)) \
                   printf("assertion(%s) failed at line : %d\n",#x,__LINE__);}
#define CHECK_HANDLE(x) check_handle(x)
#else
#define DBGMSG(x)
#define ASSERT(x)
#define CHECK_HANDLE(x)
#endif

/*
 * Globals ...protect all with a global synchronization object.
 */

static int Current_handle = 0;
static int Use_devpoll = 0;
static int Max_index = 0;

/*
 * Per Poller object data.
 * Must be synchronized on a per Poller object basis.
 */

typedef struct ioevent {
  int inuse;
  int devpollfd;
  int last_index;
  int total_free;
  int left_events;
  int max_index;
  pollfd_t *pfd;
} ioevent_t;

static ioevent_t IOE_handles[MAX_HANDLES];

/*
 * Exceptions to be thrown.
 * Note : assuming all illegal argument and NULL pointer checks
 *        have already been done by the Java calling methods.
 */
static jint throwOutOfMemoryError(JNIEnv *env, const char * cause)
{
  (*env)->ThrowNew(env, (*env)->FindClass(env,"java/lang/OutOfMemoryError"),
                   cause);
  return -1;
}
static jint throwInterruptedIOException(JNIEnv *env, const char * cause)
{
  (*env)->ThrowNew(env,
                   (*env)->FindClass(env,"java/io/InterruptedIOException"),
                   cause);
  return -1;
}
static jint throwIllegalStateException(JNIEnv *env, const char * cause)
{
  (*env)->ThrowNew(env,
                   (*env)->FindClass(env,"java/lang/IllegalStateException"),
                   cause);
  return -1;
}

#define MEMORY_EXCEPTION(str) throwOutOfMemoryError(env, "Poller:" ## str)
#define STATE_EXCEPTION(str)  throwIllegalStateException(env, "Poller:" ## str)
#define INTERRUPT_EXCEPTION(str) throwInterruptedIOException(env, \
                                                             "Poller:" ## str)
jint addfd(JNIEnv *, ioevent_t *, jint, jshort);
jint removefd(JNIEnv *, ioevent_t *, jint);

/*
 * Class Poller
 * Method: nativeInit
 * Signature: ()I
 *
 * Only to be called once, right after this library is loaded,
 * so no need to deal with reentrancy here.
 * Could do as a pragma ini, but that isn't as portable.
 */
JNIEXPORT jint JNICALL Java_Poller_nativeInit(JNIEnv *env, jclass cls)
{
  int testdevpollfd;
  int i;

#ifdef DEVPOLL
  /*
   * See if we can use this much faster method
   * Note : must have fix for BUGID # 4223353 or OS can crash!
   */
  testdevpollfd = open("/dev/poll",O_RDWR);
  if (testdevpollfd >= 0) {
    /*
     * If Solaris 7, we need a patch
     * Until we know what string to search for, we'll play it
     * safe and disable this for Solaris 7.
     */

    if (!strcmp(name.release,"5.7"))
      {
        Use_devpoll = 0;
      }
    else
      {
        Use_devpoll = 1;
      }
  }

  DBGMSG(("Use_devpoll=%d\n" ,Use_devpoll));
  close(testdevpollfd);
#endif

  /*
   * For now, we optimize for Solaris 7 if /dev/poll isn't
   * available, as it is only a small % hit for Solaris < 7.
   * if ( (Use_devpoll == 0) && !strcmp(name.release,"5.6") )
   *      Use_sol7opt = 0;
   */
  Current_handle = 0;
  for (i = 0; i < MAX_HANDLES; i++) {
    IOE_handles[i].devpollfd = -1;
    IOE_handles[i].pfd = NULL;
  }

  /*
   * this tells me the max number of open filedescriptors
   */
  Max_index = sysconf(_SC_OPEN_MAX);
  if (Max_index < 0) {
    Max_index = 1024;
  }

  DBGMSG(("got sysconf(_SC_OPEN_MAX)=%d file desc\n",Max_index));

  return 0;
}

JNIEXPORT jint JNICALL Java_Poller_getNumCPUs(JNIEnv *env, jclass cls)
{
  return sysconf(_SC_NPROCESSORS_ONLN);
}

/*
 * Class:     Poller
 * Method:    nativeCreatePoller
 * Signature: (I)I
 * Note : in the case where /dev/poll doesn't exist,
 *        using more than one poll array could hurt
 *        Solaris 7 performance due to kernel caching.
 */

JNIEXPORT jint JNICALL Java_Poller_nativeCreatePoller
  (JNIEnv *env, jobject obj, jint maximum_fds)
{
  int handle, retval, i;
  ioevent_t *ioeh;

  if (maximum_fds == -1) {
    maximum_fds = Max_index;
  }
  handle = Current_handle;
  if (Current_handle >= MAX_HANDLES) {
    for (i = 0; i < MAX_HANDLES; i++) {
      if (IOE_handles[i].inuse == 0) {
        handle = i;
        break;
      }
    }
    if (handle >= MAX_HANDLES) {
      return MEMORY_EXCEPTION("CreatePoller - MAX_HANDLES exceeded");
    }
  } else {
    Current_handle++;
  }

  ioeh = &IOE_handles[handle];

  ioeh->inuse      = 1;

  ioeh->last_index = 0;
  ioeh->total_free = 0;
  ioeh->left_events = 0;
  ioeh->max_index = maximum_fds;

  retval = handle;
  if (Use_devpoll) {
    ioeh->devpollfd = open("/dev/poll",O_RDWR);
    DBGMSG(("Opened /dev/poll, set devpollfd = %d\n",ioeh->devpollfd));
    if (ioeh->devpollfd < 0) {
      Current_handle--;
      return MEMORY_EXCEPTION("CreatePoller - can\'t open /dev/poll");
    }
  }
  ioeh->pfd = malloc(maximum_fds * sizeof(pollfd_t));
  if (ioeh->pfd == NULL) {
    Current_handle--;
    return MEMORY_EXCEPTION("CreatePoller - malloc failure");
  }

  return retval;
}

/*
 * Class:     Poller
 * Method:    nativeDestroyPoller
 * Signature: (I)V
 */
JNIEXPORT void JNICALL Java_Poller_nativeDestroyPoller
  (JNIEnv *env, jobject obj, jint handle)
{

  ioevent_t *ioeh;

  if (handle < 0 || handle > MAX_HANDLES)
    {
      STATE_EXCEPTION("DestroyPoller - handle out of range");
      return;
    }

  ioeh = &IOE_handles[handle];
  ioeh->inuse = 0;
  if (Use_devpoll) {
    close(ioeh->devpollfd);
  }
  free(ioeh->pfd);
}

#ifdef DEBUG
static void check_handle(ioevent_t *ioeh)
{
  int i,used,unused;

  used=unused=0;
  for (i = 0; i < ioeh->last_index; i++)
    {
      if (ioeh->pfd[i].fd == -1)
        unused++;
      else
        used++;
    }
  if (unused != ioeh->total_free)
    printf("WARNING : found %d free, claimed %d.  Used : %d\n",
           unused, ioeh->total_free, used);
}
#endif

/*
 * Class:     Poller
 * Method:    nativeAddFd
 * Signature: (IIS)I
 *
 * Currently doesn't check to make sure we aren't adding
 * an fd already added (no problem for /dev/poll...just
 * an array waster for poll()).
 */
JNIEXPORT jint JNICALL Java_Poller_nativeAddFd
  (JNIEnv *env, jobject obj, jint handle, jint fd, jshort events)
{
  int retval;
  ioevent_t *ioeh;

  if (handle < 0 || handle > MAX_HANDLES)
    return STATE_EXCEPTION("AddFd - handle out of range");

  ioeh = &IOE_handles[handle];

  CHECK_HANDLE(ioeh);

  #ifdef DEVPOLL
  if (Use_devpoll)
    {
      int i;
      pollfd_t pollelt;

      /*
       * use /dev/poll
       */
      pollelt.fd = fd;
      pollelt.events = events;
      if ((i = write(ioeh->devpollfd, &pollelt, sizeof(pollfd_t))) !=
          sizeof(pollfd_t)) {
        DBGMSG(("write to devpollfd=%d showed %d bytes out of %d\n",
                ioeh->devpollfd,i,sizeof(pollfd_t)));
        return STATE_EXCEPTION("AddFd - /dev/poll add failure");
      }
    else
      {
        retval = fd;
      }
    }
  else
  #endif
    { /* no /dev/poll available */
      retval = addfd(env, ioeh, fd, events);
    }
  return retval;
}

/*
 * Addfd to pollfd array...optimized for Solaris 7
 */
jint addfd(JNIEnv *env, ioevent_t *ioeh, jint fd, jshort events)
{
  int idx;

  if (ioeh->total_free)
    {
      /*
       * Traversing from end because that's where we pad.
       */
      ioeh->total_free--;
      for (idx = ioeh->last_index - 1; idx >= 0; idx--) {
        if (ioeh->pfd[idx].fd == -1)
          break;
      }
    }
  else if (ioeh->last_index >= ioeh->max_index)
    {
      return MEMORY_EXCEPTION("AddFd - too many fds");
    }
  else
    {
      int i;
      int new_total;
      /*
       * For Solaris 7, want to add some growth space
       * and fill extras with fd=-1.  This allows for
       * kernel poll() implementation to perform optimally.
       */
      new_total = ioeh->last_index;
      new_total += (new_total/10) + 1; /* bump size by 10% */
      if (new_total > ioeh->max_index)
        new_total = ioeh->max_index;
      for (i = ioeh->last_index; i <= new_total; i++)
        {
          ioeh->pfd[i].fd = -1;
        }
      idx = ioeh->last_index;
      ioeh->total_free = new_total - ioeh->last_index - 1;
      DBGMSG(("Just grew from %d to %d in size\n",
              ioeh->last_index, new_total));
      ioeh->last_index = new_total;
    }
  ASSERT((idx >= 0) && (idx <= ioeh->max_index));
  ASSERT(ioeh->pfd[idx].fd == -1);
  ioeh->pfd[idx].fd = fd;
  ioeh->pfd[idx].events = events;
  ioeh->pfd[idx].revents = 0;

  CHECK_HANDLE(ioeh);

  return fd;
}

/*
 * Class:     Poller
 * Method:    nativeRemoveFd
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_Poller_nativeRemoveFd
  (JNIEnv *env, jobject obj, jint handle, jint fd)
{
  ioevent_t *ioeh;

  if (handle < 0 || handle > MAX_HANDLES)
    return STATE_EXCEPTION("RemoveFd - handle out of range");

  ioeh = &IOE_handles[handle];

  #ifdef DEVPOLL
  if (Use_devpoll)
    {
      /*
       * use /dev/poll - currently no need for locking here.
       */
      pollfd_t pollelt;

      pollelt.fd = fd;
      pollelt.events = POLLREMOVE;
      if (write(ioeh->devpollfd, &pollelt,
                sizeof(pollfd_t) ) != sizeof(pollfd_t))
        {
          return STATE_EXCEPTION("RemoveFd - /dev/poll failure");
        }
    }
  else
  #endif DEVPOLL
    {
      return removefd(env, ioeh,fd);
    }
}
/*
 * remove from pollfd array...optimize for Solaris 7
 */
jint removefd(JNIEnv *env, ioevent_t *ioeh, jint fd)
{
  int i;
  int found = 0;

    { /* !Use_devpoll */
      for (i = 0; i < ioeh->last_index; i++)
        {
          if (ioeh->pfd[i].fd == fd)
            {
              ioeh->pfd[i].fd = -1;
              found = 1;
              break;
            }
        }
      if (!found)
        {
          return STATE_EXCEPTION("RemoveFd - no such fd");
        }
      ioeh->left_events = 0; /* Have to go back to the kernel */
      ioeh->total_free++;
      /*
       * Shrinking pool if > 33% empty. Just don't do this often!
       */
      if ( (ioeh->last_index > 100) &&
           (ioeh->total_free > (ioeh->last_index / 3)) )
        {
          int j;
          /*
           * we'll just bite the bullet here, since we're > 33% empty.
           * walk through and eliminate -1 fd values, shrink total
           * size to still have ~ 10 fd==-1 values at end.
           * Start at end (since we pad here) and, when we find fd != -1,
           * swap with an earlier fd == -1 until we have all -1 values
           * at the end.
           */
          CHECK_HANDLE(ioeh);
          for (i = ioeh->last_index - 1, j = 0; i > j; i--)
            {
              if (ioeh->pfd[i].fd != -1)
                {
                  while ( (j < i) && (ioeh->pfd[j].fd != -1) )
                    j++;
                  DBGMSG( ("i=%d,j=%d,ioeh->pfd[j].fd=%d\n",
                           i, j, ioeh->pfd[j].fd) );
                  if (j < i)
                      {
                        ASSERT(ioeh->pfd[j].fd == -1);
                        ioeh->pfd[j].fd = ioeh->pfd[i].fd;
                        ioeh->pfd[j].events = ioeh->pfd[i].events;
                        ioeh->pfd[i].fd = -1;
                      }
                }
            }
          DBGMSG(("Just shrunk from %d to %d in size\n",
                  ioeh->last_index, j+11));
          ioeh->last_index = j + 11; /* last_index always 1 greater */
          ioeh->total_free = 10;
          CHECK_HANDLE(ioeh);
        }
    } /* !Use_devpoll */

  return 1;
}

/*
 * Class:     Poller
 * Method:    nativeIsMember
 * Signature: (II)I
 */
JNIEXPORT jint JNICALL Java_Poller_nativeIsMember
  (JNIEnv *env, jobject obj, jint handle, jint fd)
{
  int found = 0;
  int i;
  ioevent_t *ioeh;

  if (handle < 0 || handle > MAX_HANDLES)
    return STATE_EXCEPTION("IsMember - handle out of range");

  ioeh = &IOE_handles[handle];

  #ifdef DEVPOLL
  if (Use_devpoll)
    {
      pollfd_t pfd;
      /*
       * DEVPOLL ioctl DP_ISPOLLED call to determine if fd is polled.
       */
      pfd.fd = fd;
      pfd.events = 0;
      pfd.revents = 0;
      found = ioctl(ioeh->devpollfd, DP_ISPOLLED, &pfd);
      if (found == -1)
        {
          return STATE_EXCEPTION("IsMember - /dev/poll failure");
        }
    }
  else
  #endif
    {
      for (i = 0; i < ioeh->last_index; i++)
        {
          if (fd == ioeh->pfd[i].fd)
            {
              found = 1;
              break;
            }
        }
    }

  return found;
}

/*
 * Class:     Poller
 * Method:    nativeWait
 * Signature: (II[I[SJ)I
 */
JNIEXPORT jint JNICALL Java_Poller_nativeWait
  (JNIEnv *env, jobject obj, jint handle, jint maxEvents,
   jintArray jfds, jshortArray jrevents, jlong timeout)
{
  int useEvents, count, idx;
  short *reventp;
  jint  *fdp;
  int   retval;
  ioevent_t *ioeh;
  jboolean isCopy1,isCopy2;

  if (handle < 0 || handle > MAX_HANDLES)
    return STATE_EXCEPTION("nativeWait - handle out of range");

  ioeh = &IOE_handles[handle];

  if (maxEvents == 0) /* just doing a kernel delay! */
    {
      useEvents = poll(NULL,0L,timeout);
      return 0;
    }

  #ifdef DEVPOLL
  if (Use_devpoll)
    {
      struct dvpoll dopoll;
      /*
       * DEVPOLL ioctl DP_POLL call, reading
       */
      dopoll.dp_timeout = timeout;
      dopoll.dp_nfds=maxEvents;
      dopoll.dp_fds=ioeh->pfd;

      useEvents = ioctl(ioeh->devpollfd, DP_POLL, &dopoll);
      while ((useEvents == -1) && (errno == EAGAIN))
            useEvents = ioctl(ioeh->devpollfd, DP_POLL, &dopoll);

      if (useEvents == -1)
        {
          if (errno == EINTR)
            return INTERRUPT_EXCEPTION("nativeWait - /dev/poll failure EINTR");
          else
            return STATE_EXCEPTION("nativeWait - /dev/poll failure");
        }

      reventp =(*env)->GetShortArrayElements(env,jrevents,&isCopy1);
      fdp =(*env)->GetIntArrayElements(env,jfds,&isCopy2);
      for (idx = 0,count = 0; idx < useEvents; idx++)
        {
          if (ioeh->pfd[idx].revents)
            {
              fdp[count] = ioeh->pfd[idx].fd;
              reventp[count] = ioeh->pfd[idx].revents;
              count++;
            }
        }
      if (count < useEvents)
        return STATE_EXCEPTION("Wait - Corrupted internals");

      if (isCopy1 == JNI_TRUE)
        (*env)->ReleaseShortArrayElements(env,jrevents,reventp,0);
      if (isCopy2 == JNI_TRUE)
        (*env)->ReleaseIntArrayElements(env,jfds,fdp,0);
    }
  else
  #endif
    { /* !Use_devpoll */

    /* no leftovers=>go to kernel */
      if (ioeh->left_events == 0)
        {
          useEvents = poll(ioeh->pfd,ioeh->last_index, timeout);
          while ((useEvents == -1) && (errno == EAGAIN))
            useEvents = poll(ioeh->pfd,ioeh->last_index, timeout);
          if (useEvents == -1)
            {
              if (errno == EINTR)
                return INTERRUPT_EXCEPTION("Wait - poll() failure EINTR-" \
                                           "IO interrupted.");
              else if (errno == EINVAL)
                return STATE_EXCEPTION("Wait - poll() failure EINVAL-" \
                                       "invalid args (is fdlim cur < max?)");
              else
                return STATE_EXCEPTION("Wait - poll() failure");
            }
          ioeh->left_events = useEvents;
          DBGMSG(("waitnative : poll returns : %d\n",useEvents));
        }
      else
        {  /* left over from last call */
          useEvents = ioeh->left_events;
        }

      if (useEvents > maxEvents)
        {
          useEvents = maxEvents;
        }

      ioeh->left_events -= useEvents; /* left to process */

      DBGMSG(("waitnative : left %d, use %d, max %d\n",ioeh->left_events,
              useEvents,maxEvents));

      if (useEvents > 0)
        {
          reventp =(*env)->GetShortArrayElements(env,jrevents,&isCopy1);
          fdp =(*env)->GetIntArrayElements(env,jfds,&isCopy2);
          for (idx = 0,count = 0; (idx < ioeh->last_index) &&
                 (count < useEvents); idx++)
            {
              if (ioeh->pfd[idx].revents)
                {
                  fdp[count] = ioeh->pfd[idx].fd;
                  reventp[count] = ioeh->pfd[idx].revents;
                  /* in case of leftover for next walk */
                  ioeh->pfd[idx].revents = 0;
                  count++;
                }
            }
          if (count < useEvents)
            {
              ioeh->left_events = 0;
              return STATE_EXCEPTION("Wait - Corrupted internals");
            }
          if (isCopy1 == JNI_TRUE)
            (*env)->ReleaseShortArrayElements(env,jrevents,reventp,0);
          if (isCopy2 == JNI_TRUE)
            (*env)->ReleaseIntArrayElements(env,jfds,fdp,0);
        }
    } /* !Use_devpoll */

  return useEvents;
}
