示例#1
0
文件: init.c 项目: DashYang/sim
VALUE
rsock_s_accept(VALUE klass, int fd, struct sockaddr *sockaddr, socklen_t *len)
{
    int fd2;
    int retry = 0;
    struct accept_arg arg;

    rb_secure(3);
    arg.fd = fd;
    arg.sockaddr = sockaddr;
    arg.len = len;
  retry:
    rsock_maybe_wait_fd(fd);
    fd2 = (int)BLOCKING_REGION_FD(accept_blocking, &arg);
    if (fd2 < 0) {
	switch (errno) {
	  case EMFILE:
	  case ENFILE:
	    if (retry) break;
	    rb_gc();
	    retry = 1;
	    goto retry;
	  default:
	    if (!rb_io_wait_readable(fd)) break;
	    retry = 0;
	    goto retry;
	}
	rb_sys_fail("accept(2)");
    }
    rb_update_max_fd(fd2);
    if (!klass) return INT2NUM(fd2);
    return rsock_init_sock(rb_obj_alloc(klass), fd2);
}
示例#2
0
文件: raindrops.c 项目: 7kaji/try
/*
 * call-seq:
 *	Raindrops.new(size)	-> raindrops object
 *
 * Initializes a Raindrops object to hold +size+ counters.  +size+ is
 * only a hint and the actual number of counters the object has is
 * dependent on the CPU model, number of cores, and page size of
 * the machine.  The actual size of the object will always be equal
 * or greater than the specified +size+.
 */
static VALUE init(VALUE self, VALUE size)
{
	struct raindrops *r = DATA_PTR(self);
	int tries = 1;
	size_t tmp;

	if (r->drops != MAP_FAILED)
		rb_raise(rb_eRuntimeError, "already initialized");

	r->size = NUM2SIZET(size);
	if (r->size < 1)
		rb_raise(rb_eArgError, "size must be >= 1");

	tmp = PAGE_ALIGN(raindrop_size * r->size);
	r->capa = tmp / raindrop_size;
	assert(PAGE_ALIGN(raindrop_size * r->capa) == tmp && "not aligned");

retry:
	r->drops = mmap(NULL, tmp,
	                PROT_READ|PROT_WRITE, MAP_ANON|MAP_SHARED, -1, 0);
	if (r->drops == MAP_FAILED) {
		if ((errno == EAGAIN || errno == ENOMEM) && tries-- > 0) {
			rb_gc();
			goto retry;
		}
		rb_sys_fail("mmap");
	}
	r->pid = getpid();

	return self;
}
示例#3
0
static VALUE rh_finish(VALUE self)
{
 rb_iv_set(self, "@allRows", Qnil); 
 rb_gc();
 
 return Qnil;
} // rh_finish
示例#4
0
static void
fiber_initialize_machine_stack_context(rb_fiber_t *fib, size_t size)
{
    rb_thread_t *sth = &fib->cont.saved_thread;

#ifdef _WIN32
    fib->fib_handle = CreateFiberEx(size - 1, size, 0, fiber_entry, NULL);
    if (!fib->fib_handle) {
	/* try to release unnecessary fibers & retry to create */
	rb_gc();
	fib->fib_handle = CreateFiberEx(size - 1, size, 0, fiber_entry, NULL);
	if (!fib->fib_handle) {
	    rb_raise(rb_eFiberError, "can't create fiber");
	}
    }
    sth->machine_stack_maxsize = size;
#else /* not WIN32 */
    ucontext_t *context = &fib->context;
    char *ptr;
    STACK_GROW_DIR_DETECTION;

    getcontext(context);
    ptr = fiber_machine_stack_alloc(size);
    context->uc_link = NULL;
    context->uc_stack.ss_sp = ptr;
    context->uc_stack.ss_size = size;
    makecontext(context, rb_fiber_start, 0);
    sth->machine_stack_start = (VALUE*)(ptr + STACK_DIR_UPPER(0, size));
    sth->machine_stack_maxsize = size - RB_PAGE_SIZE;
#endif
#ifdef __ia64
    sth->machine_register_stack_maxsize = sth->machine_stack_maxsize;
#endif
}
示例#5
0
文件: db.c 项目: basecamp/ruby-rpm
/*
 * Closes the database
 */
VALUE
rpm_db_close(VALUE db)
{
	db_unref((rpm_db_t*)DATA_PTR(db));
	DATA_PTR(db) = NULL;
    rb_gc();
    return Qnil;
}
示例#6
0
static VALUE dh_disconnect(VALUE self)
{
 TDSSOCKET *tds;

 Data_Get_Struct(rb_iv_get(self, "@tds_socket"), TDSSOCKET, tds);
 tds_free_socket(tds);
 rb_gc();

 return Qnil;
} // dh_disconnect
示例#7
0
static VALUE mysqlres2obj(MYSQL_RES* res)
{
    VALUE obj;
    struct mysql_res* resp;
    obj = Data_Make_Struct(cMysqlRes, struct mysql_res, 0, free_mysqlres, resp);
    resp->res = res;
    resp->freed = Qfalse;
    rb_obj_call_init(obj, 0, NULL);
    if (++store_result_count > GC_STORE_RESULT_LIMIT)
	rb_gc();
    return obj;
}
示例#8
0
static void
ca_check_mem_count()
{
  VALUE is_gc_disabled = rb_gc_enable();
  if ( is_gc_disabled ) {
    rb_gc_disable();
    return;
  }
  else if ( ca_mem_count > (ca_gc_interval * MB) ) {
    rb_gc();
    ca_mem_count = 0;
  }
}
示例#9
0
static void my_mq_notify(mqd_t des, struct sigevent *not)
{
	int rv = mq_notify(des, not);

	if (rv < 0) {
		if (errno == ENOMEM) {
			rb_gc();
			rv = mq_notify(des, not);
		}
		if (rv < 0)
			rb_sys_fail("mq_notify");
	}
}
示例#10
0
/*
=begin
--- OCIStmt#execute(svc [, iters [, mode]])
     execute statement at the ((<service context handle|OCISvcCtx>)).

     :svc
        ((<service context handle|OCISvcCtx>))
     :iters
        the number of iterations to execute.

        For select statement, if there are columns which is not defined
        by ((<OCIStmt#defineByPos>)) and this value is positive, it 
        raises exception. If zero, no exception. In any case you must define
        all columns before you call ((<OCIStmt#fetch>)).

        For non-select statement, use positive value.

        Default value is 0 for select statement, 1 for non-select statement.

        note: Current implemantation doesn't support array fetch and batch mode, so
        valid value is 0 or 1.
     :mode
        ((|OCI_DEFAULT|)), ((|OCI_BATCH_ERRORS|)), ((|OCI_COMMIT_ON_SUCCESS|)),
        ((|OCI_DESCRIBE_ONLY|)), ((|OCI_EXACT_FETCH|)), ((|OCI_PARSE_ONLY|)), 
        any combinations of previous values, or ((|OCI_STMT_SCROLLABLE_READONLY|)).
        Default value is ((|OCI_DEFAULT|)).

        ((|OCI_BATCH_ERRORS|)) and ((|OCI_STMT_SCROLLABLE_READONLY|)) are not
        supported by current implementation.

     correspond native OCI function: ((|OCIStmtExecute|))
=end
*/
static VALUE oci8_stmt_execute(int argc, VALUE *argv, VALUE self)
{
  VALUE vsvc;
  VALUE viters;
  VALUE vmode;
  oci8_handle_t *h;
  oci8_handle_t *svch;
  ub4 mode;
  ub4 iters;
  ub2 stmt_type;
  sword rv;

  rb_scan_args(argc, argv, "12", &vsvc, &viters, &vmode);
  Get_Handle(self, h); /* 0 */
  Check_Handle(vsvc, OCISvcCtx, svch); /* 1 */
  if (argc >= 2) {
    iters = NUM2UINT(viters); /* 2 */
  } else {
    rv = OCIAttrGet(h->hp, OCI_HTYPE_STMT, &stmt_type, 0, OCI_ATTR_STMT_TYPE, h->errhp);
    if (rv != OCI_SUCCESS) {
      oci8_raise(h->errhp, rv, h->hp);
    }
    if (stmt_type == OCI_STMT_SELECT) {
      /* for select statement, default value 0. */
      iters = 0;
    } else {
      /* for non-select statement, default value 0. */
      iters = 1;
    }
  }
  Get_Int_With_Default(argc, 3, vmode, mode, OCI_DEFAULT); /* 3 */

  if (iters > 1) {
    rb_raise(rb_eArgError, "current implementation doesn't support array fatch or batch mode");
  }

  rv = OCIStmtExecute(svch->hp, h->hp, h->errhp, iters, 0, NULL, NULL, mode);
  if (rv == OCI_ERROR) {
    sb4 errcode;
    OCIErrorGet(h->errhp, 1, NULL, &errcode, NULL, 0, OCI_HTYPE_ERROR);
    if (errcode == 1000) {
      /* run GC to close unreferred cursors when ORA-01000 (maximum open cursors exceeded). */
      rb_gc();
      rv = OCIStmtExecute(svch->hp, h->hp, h->errhp, iters, 0, NULL, NULL, mode);
    }
  }
  if (IS_OCI_ERROR(rv)) {
    oci8_raise(h->errhp, rv, h->hp);
  }
  return self;
}
示例#11
0
文件: accept.c 项目: simplegeo/kgio
static VALUE
my_accept(struct accept_args *a, int force_nonblock)
{
	int client_fd;
	VALUE client_io;
	int retried = 0;

retry:
	client_fd = thread_accept(a, force_nonblock);
	if (client_fd == -1) {
		switch (errno) {
		case EAGAIN:
			if (force_nonblock)
				return Qnil;
			a->fd = my_fileno(a->accept_io);
			set_blocking_or_block(a->fd);
#ifdef ECONNABORTED
		case ECONNABORTED:
#endif /* ECONNABORTED */
#ifdef EPROTO
		case EPROTO:
#endif /* EPROTO */
		case EINTR:
			a->fd = my_fileno(a->accept_io);
			goto retry;
		case ENOMEM:
		case EMFILE:
		case ENFILE:
#ifdef ENOBUFS
		case ENOBUFS:
#endif /* ENOBUFS */
			if (!retried) {
				retried = 1;
				errno = 0;
				rb_gc();
				goto retry;
			}
		default:
			rb_sys_fail("accept");
		}
	}
	client_io = sock_for_fd(a->accepted_class, client_fd);
	post_accept(a->accept_io, client_io);

	if (a->addr)
		in_addr_set(client_io,
		            (struct sockaddr_storage *)a->addr, *a->addrlen);
	else
		rb_ivar_set(client_io, iv_kgio_addr, localhost);
	return client_io;
}
示例#12
0
VALUE callFramework(VALUE hashReq) {
    VALUE callres = rb_funcall(framework, framework_mid, 1, hashReq);
	
	if (TYPE(callres)!=T_STRING) {
		RAWLOG_INFO1("Method call result type = %s", rb_type_to_s(callres));
		return rb_str_new2("Error");//TBD: Supply html description of the error
	}

    rb_gc_register_mark_object(callres);
	//TBD: need to cleanup memory
	rb_gc();

	return callres;
}
示例#13
0
/*
 * call-seq:
 *
 *	Kgio::File.tryopen(filename, [, mode [, perm]])	-> Kgio::File or Symbol
 *
 * Returns a Kgio::File object on a successful open.  +filename+ is a
 * path to any file on the filesystem.  If specified, +mode+ is a bitmask
 * of flags (see IO.sysopen) and +perm+ should be an octal number.
 *
 * This does not raise errors for most failures, but installs returns a
 * Ruby symbol for the constant in the Errno::* namespace.
 *
 * Common error symbols are:
 *
 * - :ENOENT
 * - :EACCES
 *
 * See your open(2) manpage for more information on open(2) errors.
 */
static VALUE s_tryopen(int argc, VALUE *argv, VALUE klass)
{
	int fd;
	VALUE pathname, flags, mode;
	struct open_args o;
	int retried = 0;
	VALUE rv;

	rb_scan_args(argc, argv, "12", &pathname, &flags, &mode);
	if (rb_respond_to(pathname, id_to_path))
		pathname = rb_funcall(pathname, id_to_path, 0);
	o.pathname = StringValueCStr(pathname);

	switch (TYPE(flags)) {
	case T_NIL: o.flags = O_RDONLY; break;
	case T_FIXNUM: o.flags = FIX2INT(flags); break;
	case T_BIGNUM: o.flags = NUM2INT(flags); break;
	default: rb_raise(rb_eArgError, "flags must be an Integer");
	}
	switch (TYPE(mode)) {
	case T_NIL: o.mode = 0666; break;
	case T_FIXNUM: o.mode = FIX2INT(mode); break;
	case T_BIGNUM: o.mode = NUM2INT(mode); break;
	default: rb_raise(rb_eArgError, "mode must be an Integer");
	}

retry:
	fd = (int)rb_thread_blocking_region(nogvl_open, &o, RUBY_UBF_IO, 0);
	if (fd < 0) {
		if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
			rb_gc();
			if (retried)
				rb_sys_fail(o.pathname);
			retried = 1;
			goto retry;
		}
		if (fd < 0) {
			int saved_errno = errno;

			if (!st_lookup(errno2sym, (st_data_t)errno, &rv)) {
				errno = saved_errno;
				rb_sys_fail(o.pathname);
			}
			return rv;
		}
	}
	rv = rb_funcall(klass, id_for_fd, 1, INT2FIX(fd));
	set_file_path(rv, pathname);
	return rv;
}
示例#14
0
static VALUE alloc_media(VALUE self) {

    // Fixes the problem where GC only runs on exit,
    // so in a script that opens a lot of media files
    // it runs out of memory
    rb_gc();

    AVFormatContext * fmt_ctx = av_alloc_format_context();
    VALUE obj;
    fmt_ctx->oformat = NULL;
    fmt_ctx->iformat = NULL;

    obj = Data_Wrap_Struct(self, 0, free_media, fmt_ctx);
    return obj;
}
示例#15
0
static int zkrb_dup(int orig) {
    int fd;

    fd = dup(orig);
    if (fd < 0) {
        if (errno == EMFILE || errno == ENFILE || errno == ENOMEM) {
            rb_gc();
            fd = dup(orig);
        }
        if (fd < 0) {
            rb_sys_fail(0);
        }
    }
    return fd;
}
示例#16
0
static VALUE
bug_str_cstr_term(VALUE str)
{
    long len;
    char *s;
    int c;
    rb_encoding *enc;

    len = RSTRING_LEN(str);
    s = StringValueCStr(str);
    rb_gc();
    enc = rb_enc_get(str);
    c = rb_enc_codepoint(&s[len], &s[len+rb_enc_mbminlen(enc)], enc);
    return INT2NUM(c);
}
示例#17
0
文件: init.c 项目: DashYang/sim
int
rsock_socket(int domain, int type, int proto)
{
    int fd;

    fd = rsock_socket0(domain, type, proto);
    if (fd < 0) {
       if (errno == EMFILE || errno == ENFILE) {
           rb_gc();
           fd = rsock_socket0(domain, type, proto);
       }
    }
    if (0 <= fd)
        rb_update_max_fd(fd);
    return fd;
}
示例#18
0
VALUE callServeIndex(char* index_name) {
    VALUE callres;
    //RhoSetCurAppPath(index_name);
	callres = rb_funcall(framework, framework_mid2, 1, RhoPreparePath(rb_str_new2(index_name)));
	
	if (TYPE(callres)!=T_STRING) {
		RAWLOG_INFO1("Method call result type = %s", rb_type_to_s(callres));
		return rb_str_new2("Error");//TBD: Supply html description of the error
	}
    rb_gc_register_mark_object(callres);

	//TBD: need to cleanup memory
	rb_gc();
	
	return callres;
}
示例#19
0
static VALUE exec_sql(cb_arg_t *arg)
{
    ub4 pos;
    sword rv;

    rv = OCIHandleAlloc(oci8_envhp, (dvoid*)&arg->stmtp, OCI_HTYPE_STMT, 0, NULL);
    if (rv != OCI_SUCCESS) {
        oci8_env_raise(oci8_envhp, rv);
    }
    chker2(OCIStmtPrepare(arg->stmtp, oci8_errhp, (text*)arg->sql_text,
                          strlen(arg->sql_text), OCI_NTV_SYNTAX, OCI_DEFAULT),
           &arg->svcctx->base);
    for (pos = 0; pos < arg->num_define_vars; pos++) {
        arg->define_vars[pos].hp = NULL;
        chker3(OCIDefineByPos(arg->stmtp, (OCIDefine**)&arg->define_vars[pos].hp,
                              oci8_errhp, pos + 1, arg->define_vars[pos].valuep,
                              arg->define_vars[pos].value_sz,
                              arg->define_vars[pos].dty, arg->define_vars[pos].indp,
                              arg->define_vars[pos].alenp, NULL, OCI_DEFAULT),
               &arg->svcctx->base, arg->stmtp);
    }
    for (pos = 0; pos < arg->num_bind_vars; pos++) {
        arg->bind_vars[pos].hp = NULL;
        chker3(OCIBindByPos(arg->stmtp, (OCIBind**)&arg->bind_vars[pos].hp,
                            oci8_errhp, pos + 1, arg->bind_vars[pos].valuep,
                            arg->bind_vars[pos].value_sz, arg->bind_vars[pos].dty,
                            arg->bind_vars[pos].indp, arg->bind_vars[pos].alenp,
                            NULL, 0, NULL, OCI_DEFAULT),
               &arg->svcctx->base, arg->stmtp);
    }
    rv = OCIStmtExecute_nb(arg->svcctx, arg->svcctx->base.hp.svc, arg->stmtp, oci8_errhp, 1, 0, NULL, NULL, OCI_DEFAULT);
    if (rv == OCI_ERROR) {
        if (oci8_get_error_code(oci8_errhp) == 1000) {
            /* run GC to close unreferred cursors
             * when ORA-01000 (maximum open cursors exceeded).
             */
            rb_gc();
            rv = OCIStmtExecute_nb(arg->svcctx, arg->svcctx->base.hp.svc, arg->stmtp, oci8_errhp, 1, 0, NULL, NULL, OCI_DEFAULT);
        }
    }
    if (arg->raise_on_error) {
        chker3(rv, &arg->svcctx->base, arg->stmtp);
    }
    return (VALUE)rv;
}
示例#20
0
文件: connect.c 项目: simplegeo/kgio
static VALUE
my_connect(VALUE klass, int io_wait, int domain, void *addr, socklen_t addrlen)
{
	int fd = socket(domain, MY_SOCK_STREAM, 0);

	if (fd == -1) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
#ifdef ENOBUFS
		case ENOBUFS:
#endif /* ENOBUFS */
			errno = 0;
			rb_gc();
			fd = socket(domain, MY_SOCK_STREAM, 0);
		}
		if (fd == -1)
			rb_sys_fail("socket");
	}

#ifndef SOCK_NONBLOCK
	if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) == -1)
		close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
#endif /* SOCK_NONBLOCK */

	if (connect(fd, addr, addrlen) == -1) {
		if (errno == EINPROGRESS) {
			VALUE io = sock_for_fd(klass, fd);

			if (io_wait) {
				errno = EAGAIN;
				(void)kgio_call_wait_writable(io);
			}
			return io;
		}
		close_fail(fd, "connect");
	}
	return sock_for_fd(klass, fd);
}
示例#21
0
文件: raindrops.c 项目: 7kaji/try
static void resize(struct raindrops *r, size_t new_rd_size)
{
	size_t old_size = raindrop_size * r->capa;
	size_t new_size = PAGE_ALIGN(raindrop_size * new_rd_size);
	void *old_address = r->drops;
	void *rv;

	if (r->pid != getpid())
		rb_raise(rb_eRuntimeError, "cannot mremap() from child");

	rv = mremap(old_address, old_size, new_size, MREMAP_MAYMOVE);
	if (rv == MAP_FAILED) {
		if (errno == EAGAIN || errno == ENOMEM) {
			rb_gc();
			rv = mremap(old_address, old_size, new_size, 0);
		}
		if (rv == MAP_FAILED)
			rb_sys_fail("mremap");
	}
	r->drops = rv;
	r->size = new_rd_size;
	r->capa = new_size / raindrop_size;
	assert(r->capa >= r->size && "bad sizing");
}
示例#22
0
/* try to use SOCK_NONBLOCK and SOCK_CLOEXEC */
static int my_socket(int domain)
{
	int fd;

retry:
	fd = socket(domain, MY_SOCK_STREAM, 0);

	if (fd < 0) {
		switch (errno) {
		case EMFILE:
		case ENFILE:
#ifdef ENOBUFS
		case ENOBUFS:
#endif /* ENOBUFS */
			errno = 0;
			rb_gc();
			fd = socket(domain, MY_SOCK_STREAM, 0);
			break;
		case EINVAL:
			if (MY_SOCK_STREAM != SOCK_STREAM) {
				MY_SOCK_STREAM = SOCK_STREAM;
				goto retry;
			}
		}
		if (fd < 0)
			rb_sys_fail("socket");
	}

	if (MY_SOCK_STREAM == SOCK_STREAM) {
		if (fcntl(fd, F_SETFL, O_RDWR | O_NONBLOCK) < 0)
			close_fail(fd, "fcntl(F_SETFL, O_RDWR | O_NONBLOCK)");
		rb_fd_fix_cloexec(fd);
	}

	return fd;
}
示例#23
0
/*
 * call-seq:
 *	POSIX_MQ.new(name [, flags [, mode [, mq_attr]])	=> mq
 *
 * Opens a POSIX message queue given by +name+.  +name+ should start
 * with a slash ("/") for portable applications.
 *
 * If a Symbol is given in place of integer +flags+, then:
 *
 * * +:r+ is equivalent to IO::RDONLY
 * * +:w+ is equivalent to IO::CREAT|IO::WRONLY
 * * +:rw+ is equivalent to IO::CREAT|IO::RDWR
 *
 * +mode+ is an integer and only used when IO::CREAT is used.
 * +mq_attr+ is a POSIX_MQ::Attr and only used if IO::CREAT is used.
 * If +mq_attr+ is not specified when creating a queue, then the
 * system defaults will be used.
 *
 * See the manpage for mq_open(3) for more details on this function.
 */
static VALUE init(int argc, VALUE *argv, VALUE self)
{
	struct posix_mq *mq = get(self, 0);
	struct open_args x;
	VALUE name, oflags, mode, attr;

	rb_scan_args(argc, argv, "13", &name, &oflags, &mode, &attr);

	switch (TYPE(oflags)) {
	case T_NIL:
		x.oflags = O_RDONLY;
		break;
	case T_SYMBOL:
		if (oflags == sym_r)
			x.oflags = O_RDONLY;
		else if (oflags == sym_w)
			x.oflags = O_CREAT|O_WRONLY;
		else if (oflags == sym_rw)
			x.oflags = O_CREAT|O_RDWR;
		else {
			oflags = rb_inspect(oflags);
			rb_raise(rb_eArgError,
			         "symbol must be :r, :w, or :rw: %s",
				 StringValuePtr(oflags));
		}
		break;
	case T_BIGNUM:
	case T_FIXNUM:
		x.oflags = NUM2INT(oflags);
		break;
	default:
		rb_raise(rb_eArgError, "flags must be an int, :r, :w, or :wr");
	}

	x.name = StringValueCStr(name);
	x.argc = 2;

	switch (TYPE(mode)) {
	case T_FIXNUM:
		x.argc = 3;
		x.mode = NUM2UINT(mode);
		break;
	case T_NIL:
		if (x.oflags & O_CREAT) {
			x.argc = 3;
			x.mode = 0666;
		}
		break;
	default:
		rb_raise(rb_eArgError, "mode not an integer");
	}

	switch (TYPE(attr)) {
	case T_STRUCT:
		x.argc = 4;
		rstruct2mqattr(&x.attr, attr, 1);

		/* principle of least surprise */
		if (x.attr.mq_flags & O_NONBLOCK)
			x.oflags |= O_NONBLOCK;
		break;
	case T_NIL:
		break;
	default:
		check_struct_type(attr);
	}

	(void)xopen(&x);
	mq->des = x.des;
	if (mq->des == MQD_INVALID) {
		switch (errno) {
		case ENOMEM:
		case EMFILE:
		case ENFILE:
		case ENOSPC:
			rb_gc();
			(void)xopen(&x);
			mq->des = x.des;
		}
		if (mq->des == MQD_INVALID)
			rb_sys_fail("mq_open");
	}

	mq->name = rb_str_new_frozen(name);
	if (x.oflags & O_NONBLOCK)
		mq->attr.mq_flags = O_NONBLOCK;

	return self;
}
示例#24
0
bool CHttpServer::run()
{
    if (verbose) LOG(INFO) + "Start HTTP server";

    if (!init())
    {
        return false;
    }

    m_active = true;

    if (!m_started_as_separated_simple_server)
        RHODESAPP().notifyLocalServerStarted();

    for(;;) 
    {
        if (verbose) RAWTRACE("Waiting for connections...");
#ifndef RHO_NO_RUBY_API
        if (rho_ruby_is_started() && (!m_started_as_separated_simple_server))
            rho_ruby_start_threadidle();
#endif
        fd_set readfds;
        FD_ZERO(&readfds);
        FD_SET(m_listener, &readfds);

        timeval tv = {0,0};
        unsigned long nTimeout = RHODESAPP().getTimer().getNextTimeout();
        tv.tv_sec = nTimeout/1000;
        tv.tv_usec = (nTimeout - tv.tv_sec*1000)*1000;
        
        
        int ret = select(m_listener+1, &readfds, NULL, NULL, (tv.tv_sec == 0 && tv.tv_usec == 0 ? 0 : &tv) );
        
        //int errsv = errno;
        
#ifndef RHO_NO_RUBY_API
        if (rho_ruby_is_started() && (!m_started_as_separated_simple_server))
            rho_ruby_stop_threadidle();
#endif
        bool bProcessed = false;
        if (ret > 0) 
        {
            if (FD_ISSET(m_listener, &readfds))
            {
                //RAWTRACE("Before accept...");
                SOCKET conn = accept(m_listener, NULL, NULL);
                //RAWTRACE("After accept...");
                if (!m_active) {
                    if (verbose) RAWTRACE("Stop HTTP server");
                    return true;
                }
                if (conn == INVALID_SOCKET) {
        #if !defined(WINDOWS_PLATFORM)
                    if (RHO_NET_ERROR_CODE == EINTR)
                        continue;
        #endif
                    if (verbose) RAWLOG_ERROR1("Can not accept connection: %d", RHO_NET_ERROR_CODE);
                    return false;
                }

                if (verbose) RAWTRACE("Connection accepted, process it...");
                VALUE val;
#ifndef RHO_NO_RUBY_API                
                if (rho_ruby_is_started() && (!m_started_as_separated_simple_server))
                {
                    if ( !RHOCONF().getBool("enable_gc_while_request") )                
                        val = rho_ruby_disable_gc();
                }
#endif
                m_sock = conn;
                bProcessed = process(m_sock);
#ifndef RHO_NO_RUBY_API
                if (rho_ruby_is_started() && (!m_started_as_separated_simple_server))
                {
                    if ( !RHOCONF().getBool("enable_gc_while_request") )
                        rho_ruby_enable_gc(val);
                }
#endif
                if (verbose) RAWTRACE("Close connected socket");
                closesocket(m_sock);
                m_sock = INVALID_SOCKET;
            }
        }
        else if ( ret == 0 ) //timeout
        {
            bProcessed = RHODESAPP().getTimer().checkTimers();
        }
        else
        {
            if (verbose) RAWLOG_ERROR1("HTTP Server select error: %d", ret);
            continue;
            //return false;
        }
#ifndef RHO_NO_RUBY_API
        if (rho_ruby_is_started() && (!m_started_as_separated_simple_server))
        {
            if ( bProcessed )
            {
                if (verbose) {
                    LOG(INFO) + "GC Start.";
                }
                rb_gc();
                if (verbose) {
                    LOG(INFO) + "GC End.";
                }
            }
        }
#endif
    }
}
示例#25
0
bool CDirectHttpRequestQueue::run( )
{
  m_server.m_pQueue = this;
  m_server.m_active = true;
  RHODESAPP().notifyLocalServerStarted();
  
  do
  {
      
      if (rho_ruby_is_started() ) {
          rho_ruby_start_threadidle();
      }
      
     m_thread.wait(-1);

      
      if (rho_ruby_is_started() ) {
          rho_ruby_stop_threadidle();
      }
      
    m_response = "";
    
    if ( m_request != 0 )
    {
      CHttpServer::ResponseWriter respWriter;
      m_server.m_localResponseWriter = &respWriter;
      
#ifndef RHO_NO_RUBY_API
      VALUE val;
      if (rho_ruby_is_started())
      {
        if ( !RHOCONF().getBool("enable_gc_while_request") )
        {
          val = rho_ruby_disable_gc();
        }
      }
#endif
      
      bool bProcessed = m_server.decide(
                                        m_request->method,
                                        m_request->uri,
                                        m_request->query,
                                        m_request->headers,
                                        m_request->body
                                        );
      
#ifndef RHO_NO_RUBY_API
      if (rho_ruby_is_started())
      {
        if ( !RHOCONF().getBool("enable_gc_while_request") )
        {
          rho_ruby_enable_gc(val);
        }
        
        if ( bProcessed )
        {
          LOG(INFO) + "GC Start.";
          rb_gc();
          LOG(INFO) + "GC End.";
        }
      }
#endif
      
      m_server.m_localResponseWriter = 0;
      
      m_response = respWriter.getResponse();
      
      pthread_cond_t* signal = m_request->signal;
      pthread_mutex_t* mutex = m_request->mutex;
      
      m_request->clear();
      m_request = 0;

      if ( (signal != 0) && (mutex!=0) )
      {
        pthread_mutex_lock(mutex);
        pthread_cond_signal(signal);
        pthread_mutex_unlock(mutex);
      }
    }
  }while (m_server.m_active);
  
  return true;
}
示例#26
0
文件: gc.c 项目: 1nueve/MacRuby
VALUE
rb_gc_start(VALUE self, SEL sel)
{
    rb_gc();
    return Qnil;
}
示例#27
0
/*
 *  call-seq:
 *     Dir.new( string ) -> aDir
 *
 *  Returns a new directory object for the named directory.
 */
static VALUE
dir_initialize(int argc, VALUE *argv, VALUE dir)
{
    struct dir_data *dp;
    static rb_encoding *fs_encoding;
    rb_encoding  *intencoding, *extencoding;
    VALUE dirname, opt;
    static VALUE sym_intenc, sym_extenc;

    if (!sym_intenc) {
	sym_intenc = ID2SYM(rb_intern("internal_encoding"));
	sym_extenc = ID2SYM(rb_intern("external_encoding"));
	fs_encoding = rb_filesystem_encoding();
    }

    intencoding = NULL;
    extencoding = fs_encoding;
    rb_scan_args(argc, argv, "11", &dirname, &opt);

    if (!NIL_P(opt)) {
        VALUE v, extenc=Qnil, intenc=Qnil;
        opt = rb_check_convert_type(opt, T_HASH, "Hash", "to_hash");

        v = rb_hash_aref(opt, sym_intenc);
        if (!NIL_P(v)) intenc = v;
        v = rb_hash_aref(opt, sym_extenc);
        if (!NIL_P(v)) extenc = v;

	if (!NIL_P(extenc)) {
	    extencoding = rb_to_encoding(extenc);
	    if (!NIL_P(intenc)) {
		intencoding = rb_to_encoding(intenc);
		if (extencoding == intencoding) {
		    rb_warn("Ignoring internal encoding '%s': it is identical to external encoding '%s'",
			    RSTRING_PTR(rb_inspect(intenc)),
			    RSTRING_PTR(rb_inspect(extenc)));
		    intencoding = NULL;
		}
	    }
	}
	else if (!NIL_P(intenc)) {
	    rb_raise(rb_eArgError, "External encoding must be specified when internal encoding is given");
	}
    }

    {
	rb_encoding  *dirname_encoding = rb_enc_get(dirname);
	if (rb_usascii_encoding() != dirname_encoding
	    && rb_ascii8bit_encoding() != dirname_encoding
#if defined __APPLE__
	    && rb_utf8_encoding() != dirname_encoding
#endif
	    && extencoding != dirname_encoding) {
	    if (!intencoding) intencoding = dirname_encoding;
	    dirname = rb_str_transcode(dirname, rb_enc_from_encoding(extencoding));
	}
    }
    FilePathValue(dirname);

    Data_Get_Struct(dir, struct dir_data, dp);
    if (dp->dir) closedir(dp->dir);
    if (dp->path) xfree(dp->path);
    dp->dir = NULL;
    dp->path = NULL;
    dp->intenc = intencoding;
    dp->extenc = extencoding;
    dp->dir = opendir(RSTRING_PTR(dirname));
    if (dp->dir == NULL) {
	if (errno == EMFILE || errno == ENFILE) {
	    rb_gc();
	    dp->dir = opendir(RSTRING_PTR(dirname));
	}
	if (dp->dir == NULL) {
	    rb_sys_fail(RSTRING_PTR(dirname));
	}
    }
    dp->path = strdup(RSTRING_PTR(dirname));

    return dir;
}