Example #1
0
JNIEXPORT void JNICALL
Java_org_apache_hadoop_net_unix_DomainSocketWatcher_00024FdSet_add(
JNIEnv *env, jobject obj, jint fd)
{
  struct fd_set_data *sd, *nd;
  struct pollfd *pollfd;

  sd = (struct fd_set_data*)(intptr_t)(*env)->
    GetLongField(env, obj, fd_set_data_fid);
  if (sd->used_size + 1 > sd->alloc_size) {
    nd = realloc(sd, sizeof(struct fd_set_data) +
            (sizeof(struct pollfd) * sd->alloc_size * 2));
    if (!nd) {
      (*env)->Throw(env, newRuntimeException(env, "out of memory adding "
            "another fd to DomainSocketWatcher#FdSet.  we have %d already",
            sd->alloc_size));
      return;
    }
    nd->alloc_size = nd->alloc_size * 2;
    (*env)->SetLongField(env, obj, fd_set_data_fid, (jlong)(intptr_t)nd);
    sd = nd;
  }
  pollfd = &sd->pollfd[sd->used_size];
  sd->used_size++;
  pollfd->fd = fd;
  pollfd->events = POLLIN | POLLHUP;
  pollfd->revents = 0;
}
Example #2
0
JNIEXPORT void JNICALL
Java_org_apache_hadoop_net_unix_DomainSocketWatcher_00024FdSet_remove(
JNIEnv *env, jobject obj, jint fd)
{
  struct fd_set_data *sd;
  struct pollfd *pollfd = NULL, *last_pollfd;
  int used_size, i;

  sd = (struct fd_set_data*)(intptr_t)(*env)->
      GetLongField(env, obj, fd_set_data_fid);
  used_size = sd->used_size;
  for (i = 0; i < used_size; i++) {
    if (sd->pollfd[i].fd == fd) {
      pollfd = sd->pollfd + i;
      break;
    }
  }
  if (pollfd == NULL) {
    (*env)->Throw(env, newRuntimeException(env, "failed to remove fd %d "
          "from the FdSet because it was never present.", fd));
    return;
  }
  last_pollfd = sd->pollfd + (used_size - 1);
  if (used_size > 1) {
    // Move last pollfd to the new empty slot if needed
    pollfd->fd = last_pollfd->fd;
    pollfd->events = last_pollfd->events;
    pollfd->revents = last_pollfd->revents;
  }
  memset(last_pollfd, 0, sizeof(struct pollfd));
  sd->used_size--;
}
Example #3
0
JNIEXPORT jlong JNICALL
Java_org_apache_hadoop_net_unix_DomainSocketWatcher_00024FdSet_alloc0(
JNIEnv *env, jclass clazz)
{
  struct fd_set_data *sd;

  sd = calloc(1, sizeof(struct fd_set_data) +
              (sizeof(struct pollfd) * FD_SET_DATA_MIN_SIZE));
  if (!sd) {
    (*env)->Throw(env, newRuntimeException(env, "out of memory allocating "
                                            "DomainSocketWatcher#FdSet"));
    return 0L;
  }
  sd->alloc_size = FD_SET_DATA_MIN_SIZE;
  sd->used_size = 0;
  return (jlong)(intptr_t)sd;
}
JNIEXPORT void JNICALL
Java_org_apache_hadoop_security_JniBasedUnixGroupsMapping_anchorNative(
JNIEnv *env, jclass clazz)
{
  jobject string_clazz;

  g_log_error_method = (*env)->GetStaticMethodID(env, clazz, "logError",
        "(ILjava/lang/String;)V");
  if (!g_log_error_method) {
    return; // an exception has been raised
  }
  string_clazz = (*env)->FindClass(env, "java/lang/String");
  if (!string_clazz) {
    return; // an exception has been raised
  }
  g_string_clazz = (*env)->NewGlobalRef(env, string_clazz);
  if (!g_string_clazz) {
    jthrowable jthr = newRuntimeException(env,
        "JniBasedUnixGroupsMapping#anchorNative: failed to make "
        "a global reference to the java.lang.String class\n");
    (*env)->Throw(env, jthr);
    return;
  }
}
Example #5
0
JNIEXPORT jobject JNICALL
Java_org_apache_hadoop_net_unix_DomainSocketWatcher_00024FdSet_getAndClearReadableFds(
JNIEnv *env, jobject obj)
{
  int *carr = NULL;
  jobject jarr = NULL;
  struct fd_set_data *sd;
  int used_size, num_readable = 0, i, j;
  jthrowable jthr = NULL;

  sd = (struct fd_set_data*)(intptr_t)(*env)->
      GetLongField(env, obj, fd_set_data_fid);
  used_size = sd->used_size;
  for (i = 0; i < used_size; i++) {
    // We check for both POLLIN and POLLHUP, because on some OSes, when a socket
    // is shutdown(), it sends POLLHUP rather than POLLIN.
    if ((sd->pollfd[i].revents & POLLIN) ||
        (sd->pollfd[i].revents & POLLHUP)) {
      num_readable++;
    } else {
      sd->pollfd[i].revents = 0;
    }
  }
  if (num_readable > 0) {
    carr = malloc(sizeof(int) * num_readable);
    if (!carr) {
      jthr = newRuntimeException(env, "failed to allocate a temporary array "
            "of %d ints", num_readable);
      goto done;
    }
    j = 0;
    for (i = 0; ((i < used_size) && (j < num_readable)); i++) {
      if ((sd->pollfd[i].revents & POLLIN) ||
          (sd->pollfd[i].revents & POLLHUP)) {
        carr[j] = sd->pollfd[i].fd;
        j++;
        sd->pollfd[i].revents = 0;
      }
    }
    if (j != num_readable) {
      jthr = newRuntimeException(env, "failed to fill entire carr "
            "array of size %d: only filled %d elements", num_readable, j);
      goto done;
    }
  }
  jarr = (*env)->NewIntArray(env, num_readable);
  if (!jarr) {
    jthr = (*env)->ExceptionOccurred(env);
    (*env)->ExceptionClear(env);
    goto done;
  }
  if (num_readable > 0) {
    (*env)->SetIntArrayRegion(env, jarr, 0, num_readable, carr);
    jthr = (*env)->ExceptionOccurred(env);
    if (jthr) {
      (*env)->ExceptionClear(env);
      goto done;
    }
  }

done:
  free(carr);
  if (jthr) {
    (*env)->DeleteLocalRef(env, jarr);
    (*env)->Throw(env, jthr);
  }
  return jarr;
}