<commit_before>#include "rbuv_handle.h"

typedef struct {
  uv_handle_t *uv_handle;
} _uv_handle_on_close_arg_t;

VALUE cRbuvHandle;

/* Methods */
static VALUE rbuv_handle_ref(VALUE self);
static VALUE rbuv_handle_unref(VALUE self);
static VALUE rbuv_handle_close(VALUE self);
static VALUE rbuv_handle_is_active(VALUE self);
static VALUE rbuv_handle_is_closed(VALUE self);
static VALUE rbuv_handle_is_closing(VALUE self);

/* Private methods */
static void _uv_handle_close(uv_handle_t *uv_handle);
static void _uv_handle_on_close(uv_handle_t *uv_handle);
static void _uv_handle_on_close_no_gvl(_uv_handle_on_close_arg_t *arg);

void Init_rbuv_handle() {
  cRbuvHandle = rb_define_class_under(mRbuv, "Handle", rb_cObject);
  rb_undef_alloc_func(cRbuvHandle);

  rb_define_method(cRbuvHandle, "ref", rbuv_handle_ref, 0);
  rb_define_method(cRbuvHandle, "unref", rbuv_handle_unref, 0);
  rb_define_method(cRbuvHandle, "close", rbuv_handle_close, 0);
  rb_define_method(cRbuvHandle, "active?", rbuv_handle_is_active, 0);
  rb_define_method(cRbuvHandle, "closing?", rbuv_handle_is_closing, 0);
  rb_define_method(cRbuvHandle, "closed?", rbuv_handle_is_closed, 0);
}

// this is called when the ruby CG is freeing a Rbuv::Loop
// the loop in turn call this method for each associated handle, here we remove
// any reference to the dying loop, for libuv happiness we also close the handle
// if it has not been closed before
void rbuv_handle_unregister_loop(rbuv_handle_t *rbuv_handle) {
  rbuv_handle->loop = Qnil;
  if (rbuv_handle->uv_handle != NULL) {
    if (_rbuv_handle_is_closing(rbuv_handle)) {
      rb_warn("The GC freed Rbuv::Loop before the Rbuv::Handle#close completed. Consider using Rbuv::Loop#dispose\n");
    } else {
      rb_warn("The GC freed Rbuv::Loop before the Rbuv::Handle#close is called. Consider using Rbuv::Loop#dispose\n");
      uv_close(rbuv_handle->uv_handle, NULL);
      rbuv_handle->uv_handle = NULL;
      free(rbuv_handle->uv_handle);
    }
  }
}

// this is called when the ruby CG is freeing a Rbuv::Handle
void rbuv_handle_free(rbuv_handle_t *rbuv_handle) {
  RBUV_DEBUG_LOG_DETAIL("rbuv_handle: %p, uv_handle: %p", rbuv_handle, rbuv_handle->uv_handle);
  if ((TYPE(rbuv_handle->loop) != T_NONE) && (rbuv_handle->loop != Qnil)) {

    // dont call if the loop is about to be GC'd
    if (TYPE(rbuv_handle->loop) != T_ZOMBIE) {
      rbuv_loop_t *rbuv_loop;
      rbuv_loop = (rbuv_loop_t*)DATA_PTR(rbuv_handle->loop);
      rbuv_loop_unregister_handle(rbuv_loop, rbuv_handle);
    }
    if (rbuv_handle->uv_handle != NULL) {
      if (_rbuv_handle_is_closing(rbuv_handle)) {
        rb_warn("The GC freed the Rbuv::Handle before #close completed.Consider using Rbuv::Loop#dispose\n");
      } else {
        rb_warn("The GC freed the Rbuv::Handle before #close is called.Consider using Rbuv::Loop#dispose\n");
        uv_close(rbuv_handle->uv_handle, NULL);
      }
    }
  }
  if (rbuv_handle->uv_handle != NULL) {
    free(rbuv_handle->uv_handle);
  }
  free(rbuv_handle);
}<commit_msg>Rubinius does not have T_ZOMBIE defined, nor its semantics<commit_after>#include "rbuv_handle.h"

typedef struct {
  uv_handle_t *uv_handle;
} _uv_handle_on_close_arg_t;

VALUE cRbuvHandle;

/* Methods */
static VALUE rbuv_handle_ref(VALUE self);
static VALUE rbuv_handle_unref(VALUE self);
static VALUE rbuv_handle_close(VALUE self);
static VALUE rbuv_handle_is_active(VALUE self);
static VALUE rbuv_handle_is_closed(VALUE self);
static VALUE rbuv_handle_is_closing(VALUE self);

/* Private methods */
static void _uv_handle_close(uv_handle_t *uv_handle);
static void _uv_handle_on_close(uv_handle_t *uv_handle);
static void _uv_handle_on_close_no_gvl(_uv_handle_on_close_arg_t *arg);

void Init_rbuv_handle() {
  cRbuvHandle = rb_define_class_under(mRbuv, "Handle", rb_cObject);
  rb_undef_alloc_func(cRbuvHandle);

  rb_define_method(cRbuvHandle, "ref", rbuv_handle_ref, 0);
  rb_define_method(cRbuvHandle, "unref", rbuv_handle_unref, 0);
  rb_define_method(cRbuvHandle, "close", rbuv_handle_close, 0);
  rb_define_method(cRbuvHandle, "active?", rbuv_handle_is_active, 0);
  rb_define_method(cRbuvHandle, "closing?", rbuv_handle_is_closing, 0);
  rb_define_method(cRbuvHandle, "closed?", rbuv_handle_is_closed, 0);
}

// this is called when the ruby CG is freeing a Rbuv::Loop
// the loop in turn call this method for each associated handle, here we remove
// any reference to the dying loop, for libuv happiness we also close the handle
// if it has not been closed before
void rbuv_handle_unregister_loop(rbuv_handle_t *rbuv_handle) {
  rbuv_handle->loop = Qnil;
  if (rbuv_handle->uv_handle != NULL) {
    if (_rbuv_handle_is_closing(rbuv_handle)) {
      rb_warn("The GC freed Rbuv::Loop before the Rbuv::Handle#close completed. Consider using Rbuv::Loop#dispose\n");
    } else {
      rb_warn("The GC freed Rbuv::Loop before the Rbuv::Handle#close is called. Consider using Rbuv::Loop#dispose\n");
      uv_close(rbuv_handle->uv_handle, NULL);
      rbuv_handle->uv_handle = NULL;
      free(rbuv_handle->uv_handle);
    }
  }
}

// this is called when the ruby CG is freeing a Rbuv::Handle
void rbuv_handle_free(rbuv_handle_t *rbuv_handle) {
  RBUV_DEBUG_LOG_DETAIL("rbuv_handle: %p, uv_handle: %p", rbuv_handle, rbuv_handle->uv_handle);
  if ((TYPE(rbuv_handle->loop) != T_NONE) && (rbuv_handle->loop != Qnil)) {

#ifdef RBUV_RBX
    rbuv_loop_t *rbuv_loop;
    rbuv_loop = (rbuv_loop_t*)DATA_PTR(rbuv_handle->loop);
    rbuv_loop_unregister_handle(rbuv_loop, rbuv_handle);
#else
    // dont call if the loop is about to be GC'd
    if (TYPE(rbuv_handle->loop) != T_ZOMBIE) {
      rbuv_loop_t *rbuv_loop;
      rbuv_loop = (rbuv_loop_t*)DATA_PTR(rbuv_handle->loop);
      rbuv_loop_unregister_handle(rbuv_loop, rbuv_handle);
    }
#endif
    if (rbuv_handle->uv_handle != NULL) {
      if (_rbuv_handle_is_closing(rbuv_handle)) {
        rb_warn("The GC freed the Rbuv::Handle before #close completed.Consider using Rbuv::Loop#dispose\n");
      } else {
        rb_warn("The GC freed the Rbuv::Handle before #close is called.Consider using Rbuv::Loop#dispose\n");
        uv_close(rbuv_handle->uv_handle, NULL);
      }
    }
  }
  if (rbuv_handle->uv_handle != NULL) {
    free(rbuv_handle->uv_handle);
  }
  free(rbuv_handle);
}
{'fraction_non_alphanumeric': 0.10960433950223357, 'fraction_numerical': 0.0019144862795149968, 'mean_word_length': 5.092322643343051, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 32, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2721259', 'n_tokens_mistral': 2384, 'n_tokens_neox': 2303, 'n_words': 502}