예제 #1
0
파일: state.c 프로젝트: kwatch/rubinius
void state_add_cleanup(STATE, OBJECT cls, state_cleanup_func func) {
  int type = N2I(class_get_object_type(cls));

  state->type_info[type].cleanup = func;
  // printf("Registered cleanup for %p\n", module_get_name(cls));
  class_set_needs_cleanup(cls, Qtrue);
}
예제 #2
0
OBJECT float_coerce(STATE, OBJECT value) {
  if(FIXNUM_P(value)) {
    return float_new(state, (double)N2I(value));
  } else if(BIGNUM_P(value)) {
    return float_new(state, bignum_to_double(state, value));
  }
  return value;
}
예제 #3
0
static void _cpu_wake_channel_and_read(EV_P_ struct ev_io *ev, int revents) {
  STATE;
  size_t sz, total, offset;
  ssize_t i;
  char *buf;
  OBJECT ret, ba, enc;
  struct thread_info *ti = (struct thread_info*)ev->data;
  
  ti->state->pending_events--;
  
  state = ti->state;
  
  if(NIL_P(ti->buffer)) {
    ret = I2N(ti->fd);
  } else {
    ba = string_get_data(ti->buffer);
    enc = string_get_encoding(ti->buffer);
    sz = (size_t)ti->count;
    
    if(enc == SYM("buffer")) {
      offset = N2I(string_get_bytes(ti->buffer));
    } else {
      offset = 0;
    }

    /* Clamp the read size so we don't overrun */
    total = SIZE_OF_BODY(ba) - offset - 1;
    if(total < sz) {
      sz = total;
    }
    
    buf = bytearray_byte_address(state, ba);
    buf += offset;
    
    while(1) {
      i = read(ti->fd, buf, sz);
      if(i == 0) {
        ret = Qnil;
      } else if(i == -1) {
        /* If we read and got nothing, go again. We must get something.
           It might be better to re-schedule this in libev and try again,
           but libev just said SOMETHING was there... */
        if(errno == EINTR) continue;
        ret = lookuptable_fetch(state, state->global->errno_mapping, I2N(errno));
      } else {
        buf[i] = 0;
        string_set_bytes(ti->buffer, I2N(i + offset));
        
        ret = I2N(i);
      }
      break;
    }
  }
  
  cpu_channel_send(state, ti->c, ti->channel, ret);
  
  _cpu_event_unregister_info(state, ti);
}
예제 #4
0
int cpu_event_cancel_event(STATE, OBJECT oid) {
  native_int id = N2I(oid);
  struct thread_info *ti = (struct thread_info*)state->thread_infos;
  struct thread_info *tnext;

  while(ti) {
    tnext = ti->next;
    if(ti->id == id) {
      _cpu_event_unregister_info(state, ti);
      return TRUE;
    }
    ti = tnext;
  }

  return FALSE;
}
예제 #5
0
OBJECT blokenv_s_under_context2(STATE, OBJECT cmethod, OBJECT ctx, OBJECT ctx_block) {
  OBJECT obj;
  int num_lcls = N2I(cmethod_get_local_count(cmethod));
    
  obj = blokenv_allocate(state);
  blokenv_set_home(obj, ctx);
  blokenv_set_initial_ip(obj, I2N(0));
  // We have no real last since the block gets it's own method.
  // Just set this very large so that comparison for bounds
  // checks are always true.
  blokenv_set_last_ip(obj, I2N(1 << 25));
  blokenv_set_post_send(obj, I2N(0));
  blokenv_set_home_block(obj, ctx_block);
  blokenv_set_method(obj, cmethod);
  blokenv_set_local_count(obj, I2N(num_lcls));
  return obj;
}
예제 #6
0
파일: library.c 프로젝트: kwatch/rubinius
OBJECT subtend_load_library(STATE, cpu c, OBJECT path, OBJECT name) {
  dlhandle lib;
  char *c_path, *c_name;
  void (*ep)(void);
  char init[128] = "Init_";
  char *sys_name;
  rni_nmc *nmc;
  int len;
  struct stat sb;
  char *end;
  
  nmc = NULL;

  /* Try to make room for 'Init_', the extension, and a null byte */
  len = N2I(string_get_bytes(path)) + 21;

  sys_name = ALLOC_N(char, len);
  
  /* path is a string like 'ext/gzip', we turn that into 'ext/gzip.so'
     or whatever the library suffix is. */
  c_path = rbx_string_as_cstr(state, path);
  strlcpy(sys_name, c_path, len);
  end = strrchr(sys_name, '.');
  
  /* detect if the suffix is already there. */
  if(end == NULL || strcmp(end++, LIBSUFFIX)) {
    strlcat(sys_name, LIBSUFFIX, len);
  }
  
  if(stat(sys_name, &sb) == 1) {
    XFREE(sys_name);
    return I2N(0);
  }
  
  /* Open it up. If this fails, then we just pretend like
     the library isn't there. */
  lib = xdlopen(sys_name);
  if(!lib) {
    XFREE(sys_name);
    printf("Couldnt open '%s': %s\n", sys_name, xdlerror());
    /* No need to raise an exception, it's not there. */
    return I2N(0);
  }
  
  /* name is like 'gzip', we want 'Init_gzip' */
  c_name = rbx_string_as_cstr(state, name);
  strlcat(init, c_name, sizeof(init));
  
  /* Try and load the init function. */
  ep = (void (*)(void))xdlsym(lib, init);
  if(!ep) {
    XFREE(sys_name);
    /* TODO: raise an exception that the library is missing the function. */
    return I2N(1);
  } else {
    nmc = nmc_new_standalone();
    
    /* Now we need to setup the 'global' context so that stuff like
       rb_define_method works. */
    subtend_set_context(state, c, nmc);

    /* Now perform the call. */
    (*ep)();
  }
   
  /*
   * We can't close the library while there are references to the code
   * in it. For now, we just leak the library reference, but we need
   * to track it so we can clean them up at some point in the future.
   * 
  */
  
  if(nmc) XFREE(nmc);
  
  subtend_set_context(state, c, NULL);
  XFREE(sys_name);
  
  return Qtrue;
}