示例#1
0
static VALUE thread_spec_rb_thread_wait_for(VALUE self, VALUE s, VALUE ms) {
  struct timeval tv;
  tv.tv_sec = NUM2INT(s);
  tv.tv_usec = NUM2INT(ms);
  rb_thread_wait_for(tv);
  return Qnil;
}
示例#2
0
文件: thread.c 项目: 1nueve/MacRuby
static VALUE
thread_wait_for(VALUE time)
{
    const struct timeval *t = (struct timeval *)time;
    rb_thread_wait_for(*t);
    return Qnil;
}
示例#3
0
static VALUE blocking_function_execute(blocking_region_arg_t *arg)
{
    oci8_svcctx_t *svcctx = arg->svcctx;
    void *(*func)(void *) = arg->func;
    void *data = arg->data;
    struct timeval tv;
    sword rv;

    tv.tv_sec = 0;
    tv.tv_usec = 10000;
    svcctx->executing_thread = rb_thread_current();
    while ((rv = (sword)(VALUE)func(data)) == OCI_STILL_EXECUTING) {
        rb_thread_wait_for(tv);
        if (tv.tv_usec < 500000)
            tv.tv_usec <<= 1;
    }
    if (rv == OCI_ERROR) {
        if (oci8_get_error_code(oci8_errhp) == 1013) {
            OCIReset(svcctx->base.hp.ptr, oci8_errhp);
            svcctx->executing_thread = Qnil;
            rb_raise(eOCIBreak, "Canceled by user request.");
        }
    }
    svcctx->executing_thread = Qnil;
    return rv;
}
示例#4
0
/* Sits on the queue, deals with new connections*/
VALUE mtserver_fetcher_thread(VALUE self)
{
   struct timeval delay,s_delay;
   int loops=80;
   VALUE socket;
   VALUE sockets=rb_iv_get(self,"@sockets");
   delay.tv_usec=250000;
   s_delay.tv_usec=500;
   mtserver_avail_add(self);
   ++RMTServer(self)->workers;
   while (loops>0)
     {
	socket=rb_ary_shift(sockets);
	if (socket!=Qnil) 
	  {
	     mtserver_avail_dec(self);
	     if (rb_iv_get(self,"@ssl")==Qnil)
	       {		  
		  rb_funcall(self,rb_intern("_serve"),1,socket);
	       }
	     else
	       {		  
		  rb_funcall(self,rb_intern("_servessl"),1,socket);
	       }	       
	     mtserver_avail_add(self);
	  }
	else
	  {	     
	     if (RMTServer(self)->avail>1) 
	       {
		  rb_thread_wait_for(delay);
		  --loops;
	       }
	     else
	       {
		  rb_thread_wait_for(s_delay);
	       }     
	  }
     }
   mtserver_avail_dec(self);
   --RMTServer(self)->workers;
//   printf("-Thread\n");
   return Qtrue;
	     

}
static gboolean
idle(gpointer data)
{
    struct timeval wait;

    wait.tv_sec  = 0;
    wait.tv_usec = 10000; /* 10ms */

    CHECK_INTS;
    if (!rb_thread_critical) rb_thread_wait_for(wait);

    return TRUE;
}
示例#6
0
int
rb_thread_select(int max, fd_set * read, fd_set * write, fd_set * except,
		 struct timeval *timeout)
{
    if (!read && !write && !except) {
	if (!timeout) {
	    rb_thread_sleep_forever();
	    return 0;
	}
	rb_thread_wait_for(*timeout);
	return 0;
    }
    else {
	return do_select(max, read, write, except, timeout);
    }
}
示例#7
0
文件: sysvmq.c 项目: alexdean/sysvmq
// int msgctl(int msqid, int cmd, struct msqid_ds *buf);
// http://man7.org/linux/man-pages/man2/msgctl.2.html
//
// Controls the queue with IPC_SET, IPC_INFO and IPC_RMID via msgctl(2). When no
// argument is passed, it'll return the information about the queue from
// IPC_INFO.
//
// TODO: IPC_SET is currently not supported.
static VALUE
sysvmq_stats(int argc, VALUE *argv, VALUE self)
{
  struct msqid_ds info;
  VALUE info_hash;
  VALUE cmd;
  sysvmq_t* sysv;

  // Optional argument handling
  if (argc > 1) {
    rb_raise(rb_eArgError, "Wrong number of arguments (0..1)");
  }

  // Default to IPC_STAT
  cmd = argc == 1 ? argv[0] : INT2FIX(IPC_STAT);

  TypedData_Get_Struct(self, sysvmq_t, &sysvmq_type, sysv);

  // TODO: Does FIX2INT actually perform this check already?
  Check_Type(cmd, T_FIXNUM);

  while (msgctl(sysv->id, FIX2INT(cmd), &info) < 0) {
    if (errno == EINTR) {
      rb_thread_wait_for(polling_interval);
      continue;
    }
    rb_sys_fail("Failed executing msgctl(2) command.");
  }

  // Map values from struct to a hash
  // TODO: Add all the fields
  // TODO: They are probably not ints..
  info_hash = rb_hash_new();
  rb_hash_aset(info_hash, ID2SYM(rb_intern("count")),         INT2FIX(info.msg_qnum));
  rb_hash_aset(info_hash, ID2SYM(rb_intern("maximum_size")), INT2FIX(info.msg_qbytes));

  // TODO: Can probably make a better checker here for whether the struct
  // actually has the member.
  // TODO: BSD support?
#ifdef __linux__
  rb_hash_aset(info_hash, ID2SYM(rb_intern("size")), INT2FIX(info.__msg_cbytes));
#elif __APPLE__
  rb_hash_aset(info_hash, ID2SYM(rb_intern("size")), INT2FIX(info.msg_cbytes));
#endif

  return info_hash;
}
示例#8
0
文件: sysvmq.c 项目: alexdean/sysvmq
// int msgget(key_t key, int msgflg);
// http://man7.org/linux/man-pages/man2/msgget.2.html
//
// Instead of calling `msgget` method directly to get the `msgid` (the return
// value of `msgget`) from Rubyland and pass it around, it's stored internally
// in a struct only directly accessible from C-land. It's passed to all the
// other calls that require a `msgid`, for convienence and to share the buffer.
VALUE
sysvmq_initialize(VALUE self, VALUE key, VALUE buffer_size, VALUE flags)
{
  sysvmq_t* sysv;
  size_t msgbuf_size;

  // TODO: Also support string keys, so you can pass '0xDEADC0DE'
  Check_Type(key,   T_FIXNUM);
  Check_Type(flags, T_FIXNUM);
  Check_Type(buffer_size, T_FIXNUM);

  TypedData_Get_Struct(self, sysvmq_t, &sysvmq_type, sysv);

  // (key_t) is a 32-bit integer (int). It's defined as `int` (at least on OS X
  // and Linux). However, `FIX2INT()` (from Ruby) will complain if the key is
  // something in the range 2^31-2^32, because of the sign bit. We use UINT to
  // trick Ruby, so it won't complain.
  sysv->key = (key_t) FIX2UINT(key);

  while ((sysv->id = msgget(sysv->key, FIX2INT(flags))) < 0) {
    if (errno == EINTR) {
      rb_thread_wait_for(polling_interval); // TODO: Really necessary here?
      continue;
    }
    rb_sys_fail("Failed opening the message queue.");
  }

  // Allocate the msgbuf buffer once for the instance, to not allocate a buffer
  // for each message sent. This makes SysVMQ not thread-safe (requiring a
  // buffer for each thread), but is a reasonable trade-off for now for the
  // performance.
  sysv->buffer_size = (size_t) FIX2LONG(buffer_size + 1);
  msgbuf_size = sysv->buffer_size * sizeof(char) + sizeof(long);

  // Note that this is a zero-length array, so we size the struct to size of the
  // header (long, the mtype) and then the rest of the space for message buffer.
  sysv->msgbuf = (sysvmq_msgbuf_t*) xmalloc(msgbuf_size);

  return self;
}
示例#9
0
static VALUE
mutex_sleep(VALUE self, SEL sel, int argc, VALUE *argv)
{
    VALUE timeout;
    rb_scan_args(argc, argv, "01", &timeout);

    rb_mutex_unlock(self, 0);
    
    time_t beg, end;
    beg = time(0);

    if (timeout == Qnil) {
	rb_thread_sleep_forever();	
    }
    else {
	struct timeval t = rb_time_interval(timeout);
	rb_thread_wait_for(t);
    }

    end = time(0) - beg;
    return INT2FIX(end);        
}
示例#10
0
/* This thread constantly monitors the connection queue, launching new fetcher threads as
 * needed */
VALUE mtserver_monitor_thread(VALUE self)
{
   struct timeval delay;
   VALUE sockets=rb_iv_get(self,"@sockets");
   delay.tv_usec=1000000;
   while (1)
     {
	if (mtserver_get_avail(self)*2<RARRAY(sockets)->len)
	  {
	     if (RMTServer(self)->workers<FIX2INT(rb_iv_get(self,"@maxWorkers")))
	       {		    
		  rb_thread_create(mtserver_fetcher_thread,(void *)self);
	       }
		 
//	     printf("Add\n");
	  }
	
	rb_thread_wait_for(delay);
	
     }
   return Qtrue;
}
示例#11
0
文件: init.c 项目: Danylyuk/first_app
int
rsock_connect(int fd, const struct sockaddr *sockaddr, int len, int socks)
{
    int status;
    rb_blocking_function_t *func = connect_blocking;
    struct connect_arg arg;
#if WAIT_IN_PROGRESS > 0
    int wait_in_progress = -1;
    int sockerr;
    socklen_t sockerrlen;
#endif

    arg.fd = fd;
    arg.sockaddr = sockaddr;
    arg.len = len;
#if defined(SOCKS) && !defined(SOCKS5)
    if (socks) func = socks_connect_blocking;
#endif
    for (;;) {
	status = (int)BLOCKING_REGION_FD(func, &arg);
	if (status < 0) {
	    switch (errno) {
	      case EINTR:
#if defined(ERESTART)
	      case ERESTART:
#endif
		continue;

	      case EAGAIN:
#ifdef EINPROGRESS
	      case EINPROGRESS:
#endif
#if WAIT_IN_PROGRESS > 0
		sockerrlen = (socklen_t)sizeof(sockerr);
		status = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen);
		if (status) break;
		if (sockerr) {
		    status = -1;
		    errno = sockerr;
		    break;
		}
#endif
#ifdef EALREADY
	      case EALREADY:
#endif
#if WAIT_IN_PROGRESS > 0
		wait_in_progress = WAIT_IN_PROGRESS;
#endif
		status = wait_connectable(fd);
		if (status) {
		    break;
		}
		errno = 0;
		continue;

#if WAIT_IN_PROGRESS > 0
	      case EINVAL:
		if (wait_in_progress-- > 0) {
		    /*
		     * connect() after EINPROGRESS returns EINVAL on
		     * some platforms, need to check true error
		     * status.
		     */
		    sockerrlen = (socklen_t)sizeof(sockerr);
		    status = getsockopt(fd, SOL_SOCKET, SO_ERROR, (void *)&sockerr, &sockerrlen);
		    if (!status && !sockerr) {
			struct timeval tv = {0, 100000};
			rb_thread_wait_for(tv);
			continue;
		    }
		    status = -1;
		    errno = sockerr;
		}
		break;
#endif

#ifdef EISCONN
	      case EISCONN:
		status = 0;
		errno = 0;
		break;
#endif
	      default:
		break;
	    }
	}
	return status;
    }
}