示例#1
0
/*
 * Initialize new Timer
 *
 * @since 1.2.0
 *
 * The timers could used to trigger reccuring events or implement timeouts.
 * The library will call given block after time interval pass.
 *
 * @param bucket [Bucket] the connection object
 * @param interval [Fixnum] the interval in microseconds
 * @param options [Hash]
 * @option options [Boolean] :periodic (false) set it to +true+ if the timer
 *   should be triggered until it will be canceled.
 *
 * @yieldparam [Timer] timer the current timer
 *
 * @example Create regular timer for 0.5 second
 *   c.run do
 *     Couchbase::Timer.new(c, 500000) do
 *       puts "ding-dong"
 *     end
 *   end
 *
 * @example Create periodic timer
 *   n = 10
 *   c.run do
 *     Couchbase::Timer.new(c, 500000, :periodic => true) do |tm|
 *       puts "#{n}"
 *       n -= 1
 *       tm.cancel if n.zero?
 *     end
 *   end
 *
 *
 * @return [Couchbase::Timer]
 */
    VALUE
cb_timer_init(int argc, VALUE *argv, VALUE self)
{
    struct timer_st *tm = DATA_PTR(self);
    VALUE bucket, opts, timeout, exc, cb;
    lcb_error_t err;

    rb_need_block();
    rb_scan_args(argc, argv, "21&", &bucket, &timeout, &opts, &cb);

    if (CLASS_OF(bucket) != cBucket) {
        rb_raise(rb_eTypeError, "wrong argument type (expected Couchbase::Bucket)");
    }
    tm->self = self;
    tm->callback = cb;
    tm->usec = NUM2ULONG(timeout);
    tm->bucket = DATA_PTR(bucket);
    if (opts != Qnil) {
        Check_Type(opts, T_HASH);
        tm->periodic = RTEST(rb_hash_aref(opts, sym_periodic));
    }
    tm->timer = lcb_timer_create(tm->bucket->handle, tm, tm->usec,
            tm->periodic, timer_callback, &err);
    exc = cb_check_error(err, "failed to attach the timer", Qnil);
    if (exc != Qnil) {
        rb_exc_raise(exc);
    }

    return self;
}
示例#2
0
void
rbclt_alpha_func_from_rb_value (VALUE func,
                                ClutterAlphaFunc *func_ret,
                                gpointer *data,
                                GDestroyNotify *notify)
{
  /* If there is no argument then get the function from the block */
  if (func == Qnil)
    {
      rb_need_block ();
      func = rb_block_proc ();
    }

  /* If the function is an integer constant representing a builtin
     clutter function then use the function pointer directly
     instead */
  if (FIXNUM_P (func) && FIX2INT (func) >= 0 && FIX2INT (func) < RBCLT_ALPHA_FUNC_MAP_COUNT)
    {
      *func_ret = rbclt_alpha_func_map[FIX2INT (func)].func;
      *data = NULL;
      *notify = NULL;
    }
  else
    {
      *func_ret = rbclt_alpha_func_wrapper_call;
      *data = rbclt_callback_func_new (func);
      *notify = (GDestroyNotify) rbclt_callback_func_destroy;
    }
}
示例#3
0
/* :nodoc: */
static VALUE
yielder_initialize(VALUE obj)
{
    rb_need_block();

    return yielder_init(obj, rb_block_proc());
}
示例#4
0
文件: rbuv_tcp.c 项目: rbuv/rbuv
VALUE rbuv_tcp_connect(VALUE self, VALUE ip, VALUE port) {
  VALUE block;
  const char *uv_ip;
  int uv_port;
  rbuv_tcp_t *rbuv_tcp;
  struct sockaddr_in connect_addr;
  uv_connect_t *uv_connect;

  rb_need_block();
  block = rb_block_proc();

  uv_ip = RSTRING_PTR(ip);
  uv_port = FIX2INT(port);

  Data_Get_Struct(self, rbuv_tcp_t, rbuv_tcp);
  rbuv_tcp->cb_on_connection = block;

  uv_connect = malloc(sizeof(*uv_connect));
  connect_addr = uv_ip4_addr(uv_ip, uv_port);

  RBUV_CHECK_UV_RETURN(uv_tcp_connect(uv_connect, rbuv_tcp->uv_handle,
                                      connect_addr, _uv_tcp_on_connect));

  RBUV_DEBUG_LOG_DETAIL("self: %s, ip: %s, port: %d, rbuv_tcp: %p, uv_handle: %p",
                        RSTRING_PTR(rb_inspect(self)), uv_ip, uv_port, rbuv_tcp,
                        rbuv_tcp->uv_handle);

  return self;
}
示例#5
0
/* :nodoc: */
static VALUE
generator_initialize(int argc, VALUE *argv, VALUE obj)
{
    VALUE proc;

    if (argc == 0) {
	rb_need_block();

	proc = rb_block_proc();
    }
    else {
	rb_scan_args(argc, argv, "1", &proc);

	if (!rb_obj_is_proc(proc))
	    rb_raise(rb_eTypeError,
		     "wrong argument type %s (expected Proc)",
		     rb_obj_classname(proc));

	if (rb_block_given_p()) {
	    rb_warn("given block not used");
	}
    }

    return generator_init(obj, proc);
}
示例#6
0
static VALUE
stackprof_run(int argc, VALUE *argv, VALUE self)
{
    rb_need_block();
    stackprof_start(argc, argv, self);
    rb_ensure(rb_yield, Qundef, stackprof_stop, self);
    return stackprof_results(0, 0, self);
}
示例#7
0
// Passes each line of the input to the block. This should be avoided.
static VALUE tfio_each(VALUE self) {
  rb_need_block();
  rio_rewind(self);
  VALUE str = Qnil;
  while ((str = tfio_gets(self)) != Qnil) {
    rb_yield(str);
  }
  return self;
}
示例#8
0
static VALUE zipruby_archive_replace_function(int argc, VALUE *argv, VALUE self) {
  VALUE index, flags, mtime;
  struct zipruby_archive *p_archive;
  struct zip_source *zsource;
  struct read_proc *z;
  int i_index, i_flags = 0;

  rb_scan_args(argc, argv, "12", &index, &mtime, &flags);
  rb_need_block();

  if (TYPE(index) != T_STRING && !FIXNUM_P(index)) {
    rb_raise(rb_eTypeError, "wrong argument type %s (expected Fixnum or String)", rb_class2name(CLASS_OF(index)));
  }

  if (NIL_P(mtime)) {
    mtime = rb_funcall(rb_cTime, rb_intern("now"), 0);
  } else if (!rb_obj_is_instance_of(mtime, rb_cTime)) {
    rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(mtime)));
  }

  if (!NIL_P(flags)) {
    i_flags = NUM2INT(flags);
  }

  Data_Get_Struct(self, struct zipruby_archive, p_archive);
  Check_Archive(p_archive);

  if (FIXNUM_P(index)) {
    i_index = NUM2INT(index);
  } else if ((i_index = zip_name_locate(p_archive->archive, RSTRING_PTR(index), i_flags)) == -1) {
    rb_raise(Error, "Replace file failed - %s: Archive does not contain a file", RSTRING_PTR(index));
  }

  if ((z = malloc(sizeof(struct read_proc))) == NULL) {
    zip_unchange_all(p_archive->archive);
    zip_unchange_archive(p_archive->archive);
    rb_raise(rb_eRuntimeError, "Replace failed at %d: Cannot allocate memory", i_index);
  }

  z->proc = rb_block_proc();
  rb_ary_push(p_archive->sources, z->proc);
  z->mtime = TIME2LONG(mtime);

  if ((zsource = zip_source_proc(p_archive->archive, z)) == NULL) {
    free(z);
    rb_raise(Error, "Replace failed at %d: %s", i_index, zip_strerror(p_archive->archive));
  }

  if (zip_replace(p_archive->archive, i_index, zsource) == -1) {
    zip_source_free(zsource);
    zip_unchange_all(p_archive->archive);
    zip_unchange_archive(p_archive->archive);
    rb_raise(Error, "Replace failed at %d: %s", i_index, zip_strerror(p_archive->archive));
  }

  return Qnil;
}
示例#9
0
static VALUE rb_git_treebuilder_filter(VALUE self)
{
	git_treebuilder *builder;

	rb_need_block();
	Data_Get_Struct(self, git_treebuilder, builder);

	git_treebuilder_filter(builder, &treebuilder_cb, (void *)rb_block_proc());
	return Qnil;
}
示例#10
0
static VALUE
rb_profile_block(VALUE module, VALUE usec)
{
    rb_need_block();

    profiler_start(module, usec);
    rb_yield(Qundef);
    profiler_stop(module);

    return Qnil;
}
示例#11
0
文件: elem.c 项目: luikore/cici2
// return a Timer number
DECL1(set_timer, milisec) {
	static long timer_id = 1;
	Elem* elem;
	Data_Get_Struct(self, Elem, elem);
	if (!elem || !elem->h)
		return Qnil; // TODO raise
	rb_need_block();
	// add ref to timer
	rb_funcall(runtime.internal, rb_intern("register_timer"), 2, INT2NUM(timer_id), rb_block_proc());
	SetTimer(elem->h, timer_id++, NUM2INT(milisec), cici_timer_proc);
	return INT2NUM(timer_id);
}
示例#12
0
static VALUE avl_tree_rscan_inorder( VALUE self )
{
  avl_tree_r *t;

  rb_need_block();

  Data_Get_Struct( self, avl_tree_r, t );

  avl_tree_scan_inorder( t->root, yielder );

  return Qnil;
}
示例#13
0
文件: lichxml.c 项目: mtmiron/lich
/*
 * Implements the Ruby method "LichXML#define_callback"
 *
 */
static VALUE define_rb_callback(VALUE self, VALUE rb_key)
{
	VALUE block;
	VALUE cb_hash;

	rb_need_block();

	block = rb_block_proc();
	cb_hash = rb_iv_get(self, "@cb_hash");

	rb_hash_aset(cb_hash, rb_key, block);
	return Qtrue;
}
示例#14
0
static VALUE Packer_register_type(int argc, VALUE* argv, VALUE self)
{
    PACKER(self, pk);

    int ext_type;
    VALUE ext_class;
    VALUE proc;
    VALUE arg;

    switch (argc) {
    case 2:
        /* register_type(0x7f, Time) {|obj| block... } */
        rb_need_block();
#ifdef HAVE_RB_BLOCK_LAMBDA
        proc = rb_block_lambda();
#else
        /* MRI 1.8 */
        proc = rb_block_proc();
#endif
        arg = proc;
        break;
    case 3:
        /* register_type(0x7f, Time, :to_msgpack_ext) */
        arg = argv[2];
        proc = rb_funcall(arg, rb_intern("to_proc"), 0);
        break;
    default:
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 2..3)", argc);
    }

    ext_type = rb_num2int(argv[0]);
    if(ext_type < -128 || ext_type > 127) {
        rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
    }

    ext_class = argv[1];
    if(rb_type(ext_class) != T_CLASS) {
        rb_raise(rb_eArgError, "expected Class but found %s.", rb_obj_classname(ext_class));
    }

    msgpack_packer_ext_registry_put(&pk->ext_registry, ext_class, ext_type, proc, arg);

    return Qnil;
}
示例#15
0
static VALUE zipruby_archive_add_function(int argc, VALUE *argv, VALUE self) {
  VALUE name, mtime;
  struct zipruby_archive *p_archive;
  struct zip_source *zsource;
  struct read_proc *z;

  rb_scan_args(argc, argv, "11", &name, &mtime);
  rb_need_block();
  Check_Type(name, T_STRING);

  if (NIL_P(mtime)) {
    mtime = rb_funcall(rb_cTime, rb_intern("now"), 0);
  } else if (!rb_obj_is_instance_of(mtime, rb_cTime)) {
    rb_raise(rb_eTypeError, "wrong argument type %s (expected Time)", rb_class2name(CLASS_OF(mtime)));
  }

  Data_Get_Struct(self, struct zipruby_archive, p_archive);
  Check_Archive(p_archive);

  if ((z = malloc(sizeof(struct read_proc))) == NULL) {
    zip_unchange_all(p_archive->archive);
    zip_unchange_archive(p_archive->archive);
    rb_raise(rb_eRuntimeError, "Add failed - %s: Cannot allocate memory", RSTRING_PTR(name));
  }

  z->proc = rb_block_proc();
  rb_ary_push(p_archive->sources, z->proc);
  z->mtime = TIME2LONG(mtime);

  if ((zsource = zip_source_proc(p_archive->archive, z)) == NULL) {
    free(z);
    rb_raise(Error, "Add failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
  }

  if (zip_add(p_archive->archive, RSTRING_PTR(name), zsource) == -1) {
    zip_source_free(zsource);
    zip_unchange_all(p_archive->archive);
    zip_unchange_archive(p_archive->archive);
    rb_raise(Error, "Add file failed - %s: %s", RSTRING_PTR(name), zip_strerror(p_archive->archive));
  }

  return Qnil;
}
示例#16
0
VALUE
r_gmpmod_time (VALUE self)
{
  long int __t0, __times, __t, __tmp;
  (void)self;
  __times = 1;

  rb_need_block();

  rb_yield (Qnil);
  do {
    __times <<= 1;
    __t0 = cputime ();
    for (__t = 0; __t < __times; __t++)
      {rb_yield (Qnil);}
    __tmp = cputime () - __t0;
  } while (__tmp < 250);
  return rb_float_new ((double) __tmp / __times);
}
示例#17
0
static VALUE Unpacker_register_type(int argc, VALUE* argv, VALUE self)
{
    UNPACKER(self, uk);

    int ext_type;
    VALUE proc;
    VALUE arg;
    VALUE ext_class;

    switch (argc) {
    case 1:
        /* register_type(0x7f) {|data| block... } */
        rb_need_block();
#ifdef HAVE_RB_BLOCK_LAMBDA
        proc = rb_block_lambda();
#else
        /* MRI 1.8 */
        proc = rb_block_proc();
#endif
        arg = proc;
        ext_class = Qnil;
        break;
    case 3:
        /* register_type(0x7f, Time, :from_msgpack_ext) */
        ext_class = argv[1];
        arg = argv[2];
        proc = rb_obj_method(ext_class, arg);
        break;
    default:
        rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 or 3)", argc);
    }

    ext_type = rb_num2int(argv[0]);
    if(ext_type < -128 || ext_type > 127) {
        rb_raise(rb_eRangeError, "integer %d too big to convert to `signed char'", ext_type);
    }

    msgpack_unpacker_ext_registry_put(&uk->ext_registry, ext_class, ext_type, proc, arg);

    return Qnil;
}
示例#18
0
/*
 * call-seq:
 *    Helium::Connection.new(proxy=nil) { |mac, str| ... } => Helium::Connection
 *
 * Open a Helium connection, receiving data with the provided block.
 */
static VALUE helium_rb_initialize(int argc, VALUE *argv, VALUE self)
{
  VALUE rb_proxy_addr = Qnil;
  VALUE block = Qnil;
  rb_need_block();

  rb_scan_args(argc, argv, "01&", &rb_proxy_addr, &block);

  char *proxy_addr = NULL;
  if (!NIL_P(rb_proxy_addr)) {
    proxy_addr = StringValuePtr(rb_proxy_addr);
  }

  helium_connection_t *conn = NULL;
  Data_Get_Struct(self, helium_connection_t, conn);
  helium_set_context(conn, (void *)block);
  RB_GC_GUARD(block);

  helium_open(conn, proxy_addr, helium_rb_callback);

  return self;
}
示例#19
0
文件: timer.c 项目: gregfu/rbczmq
VALUE rb_czmq_timer_s_new(int argc, VALUE *argv, VALUE timer)
{
    VALUE delay, times, proc, callback;
    size_t timer_delay;
    zmq_timer_wrapper *tr = NULL;
    rb_scan_args(argc, argv, "21&", &delay, &times, &proc, &callback);
    if (NIL_P(proc) && NIL_P(callback)) rb_raise(rb_eArgError, "no callback given!");
    if (NIL_P(proc)) {
        rb_need_block();
    } else {
        callback = proc;
    }
    if (TYPE(delay) != T_FIXNUM && TYPE(delay) != T_FLOAT) rb_raise(rb_eTypeError, "wrong delay type %s (expected Fixnum or Float)", RSTRING_PTR(rb_obj_as_string(delay)));
    Check_Type(times, T_FIXNUM);
    timer_delay = (size_t)(((TYPE(delay) == T_FIXNUM) ? FIX2LONG(delay) : RFLOAT_VALUE(delay)) * 1000); 
    timer = Data_Make_Struct(rb_cZmqTimer, zmq_timer_wrapper, rb_czmq_mark_timer, rb_czmq_free_timer_gc, tr);
    tr->cancelled = FALSE;
    tr->delay = timer_delay;
    tr->times = FIX2INT(times);
    tr->callback = callback;
    rb_obj_call_init(timer, 0, NULL);
    return timer;
}
示例#20
0
文件: rb_monitor.c 项目: caisong/wdm
static VALUE
combined_watch(BOOL recursively, int argc, VALUE *argv, VALUE self)
{
    WDM_PMonitor monitor;
    WDM_PEntry entry;
    int directory_letters_count;
    VALUE directory, flags, os_encoded_directory;
    BOOL running;

    // TODO: Maybe raise a more user-friendly error?
    rb_need_block();

    Data_Get_Struct(self, WDM_Monitor, monitor);

    EnterCriticalSection(&monitor->lock);
        running = monitor->running;
    LeaveCriticalSection(&monitor->lock);

    if ( running ) {
        rb_raise(eWDM_MonitorRunningError, "You can't watch new directories while the monitor is running!");
    }

    rb_scan_args(argc, argv, "1*", &directory, &flags);

    Check_Type(directory, T_STRING);

    entry = wdm_entry_new();
    entry->user_data->watch_childeren = recursively;
    entry->user_data->callback =  rb_block_proc();
    entry->user_data->flags = RARRAY_LEN(flags) == 0 ? WDM_MONITOR_FLAGS_DEFAULT : extract_flags_from_rb_array(flags);

    // WTF Ruby source: The original code (file.c) uses the following macro to make sure that the encoding
    // of the string is ASCII-compatible, but UTF-16LE (Windows default encoding) is not!!!
    //
    // FilePathValue(directory);

    os_encoded_directory = rb_str_encode_ospath(directory);

    // RSTRING_LEN can't be used because it would return the count of bytes the string uses in its encoding (like UTF-8).
    // UTF-8 might use more than one byte for the char, which is not needed for WCHAR strings.
    // Also, the result of MultiByteToWideChar _includes_ the NULL char at the end, which is not true for RSTRING.
    //
    // Example: 'C:\Users\Maher\Desktop\تجربة' with __ENCODING__ == UTF-8
    //   MultiByteToWideChar => 29 (28-char + null)
    //   RSTRING_LEN => 33 (23-char + 10-bytes for 5 Arabic letters which take 2 bytes each)
    //
    directory_letters_count = MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(os_encoded_directory), -1, NULL, 0);

    entry->user_data->dir = ALLOCA_N(WCHAR, directory_letters_count);

    MultiByteToWideChar(CP_UTF8, 0, RSTRING_PTR(os_encoded_directory), -1, entry->user_data->dir, directory_letters_count);

    WDM_WDEBUG("New path to watch: '%s'", entry->user_data->dir);

    entry->user_data->dir = wdm_utils_full_pathname(entry->user_data->dir);

    if ( entry->user_data->dir == 0 ) {
        wdm_entry_free(entry);
        rb_raise(eWDM_Error, "Can't get the absolute path for the passed directory: '%s'!", RSTRING_PTR(directory));
    }

    if ( ! wdm_utils_unicode_is_directory(entry->user_data->dir) ) {
        wdm_entry_free(entry);
        rb_raise(eWDM_InvalidDirectoryError, "No such directory: '%s'!", RSTRING_PTR(directory));
    }

    entry->dir_handle = CreateFileW(
        entry->user_data->dir,     // pointer to the file name
        FILE_LIST_DIRECTORY,       // access (read/write) mode
        FILE_SHARE_READ            // share mode
            | FILE_SHARE_WRITE
            | FILE_SHARE_DELETE,
        NULL,                       // security descriptor
        OPEN_EXISTING,              // how to create
        FILE_FLAG_BACKUP_SEMANTICS
            | FILE_FLAG_OVERLAPPED, // file attributes
        NULL
    );

    if ( entry->dir_handle ==  INVALID_HANDLE_VALUE ) {
        wdm_entry_free(entry);
        rb_raise(eWDM_Error, "Can't watch directory: '%s'!", RSTRING_PTR(directory));
    }

    // Store a reference to the entry instead of an event as the event
    // won't be used when using callbacks.
    entry->event_container.hEvent = wdm_monitor_callback_param_new(monitor, entry);

    wdm_monitor_update_head(monitor, entry);

    WDM_WDEBUG("Watching directory: '%s'", entry->user_data->dir);

    return Qnil;
}
示例#21
0
VALUE kernel_spec_rb_need_block(VALUE self) {
  rb_need_block();
  return Qnil;
}
示例#22
0
文件: lichxml.c 项目: mtmiron/lich
/*
 * Implements the Ruby method "LichXML#define_text_callback"
 *
 */
static VALUE define_rb_text_callback(VALUE self)
{
	rb_need_block();
	rb_iv_set(self, "@text_callback", rb_block_proc());
	return Qtrue;
}