Beispiel #1
0
static VALUE daemon_mainloop_ensure(VALUE self)
{
  int i;

  // Signal both the ruby thread and service_main thread to terminate
  SetEvent(hStopEvent);

  // Wait for ALL ruby threads to exit
  for(i=1; TRUE; i++)
  {
    VALUE list = rb_funcall(rb_cThread, rb_intern("list"), 0);

    if(RARRAY_LEN(list) <= 1)
      break;

    // This is another ugly polling loop, be as polite as possible
    rb_thread_polling();

    SetTheServiceStatus(SERVICE_STOP_PENDING, 0, i, 1000);
  }

  // Only one ruby thread
  SetEvent(hStopCompletedEvent);

  // Wait for the thread to stop BEFORE we close the hStopEvent handle
  WaitForSingleObject(hThread, INFINITE);

  // Close the event handle, ignoring failures. We may be cleaning up
  // after an exception, so let that exception fall through.
  CloseHandle(hStopEvent);

  return self;
}
Beispiel #2
0
VALUE Ruby_Service_Ctrl(VALUE self)
{
   while (WaitForSingleObject(hStopEvent,0) == WAIT_TIMEOUT)
    {
      __try
      {
         EnterCriticalSection(&csControlCode);

         // Check to see if anything interesting has been signaled
         if (waiting_control_code != IDLE_CONTROL_CODE)
         {
            if (waiting_control_code != SERVICE_CONTROL_STOP) {
                // if there is a code, create a ruby thread to deal with it
                // this might be over engineering the solution, but I don't
                // want to block Service_Ctrl longer than necessary and the
                // critical section will block it.
                VALUE EventHookHash = rb_ivar_get(self, rb_intern("@event_hooks"));

                if(EventHookHash != Qnil){
                   VALUE val = rb_hash_aref(EventHookHash, INT2NUM(waiting_control_code));

                   if(val != Qnil)
                      rb_thread_create(Service_Event_Dispatch, (void*) val);
                }
            }
            else {
               break;
            }
            waiting_control_code = IDLE_CONTROL_CODE;
         }
      }
      __finally
      {
         LeaveCriticalSection(&csControlCode);
      }

      // This is an ugly polling loop, be as polite as possible
      rb_thread_polling();
      __end_finally
   }

   // force service_stop call
   {
      VALUE EventHookHash = rb_ivar_get(self, rb_intern("@event_hooks"));

      if(EventHookHash != Qnil){
         VALUE val = rb_hash_aref(EventHookHash, INT2NUM(SERVICE_CONTROL_STOP));

         if(val!=Qnil)
            rb_thread_create(Service_Event_Dispatch, (void*) val);
      }
   }

   return Qnil;
}
Beispiel #3
0
VALUE
rb_f_kill(int argc, VALUE *argv)
{
#ifndef HAS_KILLPG
#define killpg(pg, sig) kill(-(pg), sig)
#endif
    int negative = 0;
    int sig;
    int i;
    const char *s;

    rb_secure(2);
    if (argc < 2)
	rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)");
    switch (TYPE(argv[0])) {
      case T_FIXNUM:
	sig = FIX2INT(argv[0]);
	break;

      case T_SYMBOL:
	s = rb_id2name(SYM2ID(argv[0]));
	if (!s) rb_raise(rb_eArgError, "bad signal");
	goto str_signal;

      case T_STRING:
	s = RSTRING_PTR(argv[0]);
	if (s[0] == '-') {
	    negative++;
	    s++;
	}
      str_signal:
	if (strncmp("SIG", s, 3) == 0)
	    s += 3;
	if((sig = signm2signo(s)) == 0)
	    rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);

	if (negative)
	    sig = -sig;
	break;

      default:
        {
	    VALUE str;

	    str = rb_check_string_type(argv[0]);
	    if (!NIL_P(str)) {
		s = RSTRING_PTR(str);
		goto str_signal;
	    }
	    rb_raise(rb_eArgError, "bad signal type %s",
		     rb_obj_classname(argv[0]));
	}
	break;
    }

    if (sig < 0) {
	sig = -sig;
	for (i=1; i<argc; i++) {
	    if (killpg(NUM2PIDT(argv[i]), sig) < 0)
		rb_sys_fail(0);
	}
    }
    else {
	for (i=1; i<argc; i++) {
	    if (kill(NUM2PIDT(argv[i]), sig) < 0)
		rb_sys_fail(0);
	}
    }
    rb_thread_polling();
    return INT2FIX(i-1);
}
Beispiel #4
0
VALUE
rb_f_kill(VALUE self, SEL sel, int argc, VALUE *argv)
{
    int negative = 0;
    int sig;
    int i;
    int type;
    const char *s = NULL;

    rb_secure(2);
    if (argc < 2)
	rb_raise(rb_eArgError, "wrong number of arguments -- kill(sig, pid...)");

    type = TYPE(argv[0]);
    if (type == T_FIXNUM) {
	sig = FIX2INT(argv[0]);
    }
    else {
	if (type == T_SYMBOL) {
	    s = rb_sym2name(argv[0]);
	    if (!s)
		rb_raise(rb_eArgError, "bad signal");
	}
	else if (type == T_STRING) {
	    s = RSTRING_PTR(argv[0]);
	    if (s[0] == '-') {
		negative++;
		s++;
	    }
	}
	else {
	    VALUE str;
	    str = rb_check_string_type(argv[0]);
	    if (!NIL_P(str)) {
		s = RSTRING_PTR(str);
	    }
	}
	if (s == NULL)
	    rb_raise(rb_eArgError, "bad signal type %s", rb_obj_classname(argv[0]));

	if (strncmp("SIG", s, 3) == 0)
	    s += 3;
	if ((sig = signm2signo(s)) == 0)
	    rb_raise(rb_eArgError, "unsupported name `SIG%s'", s);
	if (negative)
	    sig = -sig;
    }

    if (sig < 0) {
	sig = -sig;
	for (i = 1; i < argc; i++) {
	    if (killpg(NUM2PIDT(argv[i]), sig) < 0)
		rb_sys_fail(0);
	}
    }
    else {
	for (i = 1; i < argc; i++) {
	    if (kill(NUM2PIDT(argv[i]), sig) < 0)
		rb_sys_fail(0);
	}
    }
    rb_thread_polling();
    return INT2FIX(i - 1);
}