couchbase 1.2.0.z.beta5 → 1.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -22,13 +22,13 @@ cb_observe_callback(lcb_t handle, const void *cookie, lcb_error_t error, const l
22
22
  {
23
23
  struct cb_context_st *ctx = (struct cb_context_st *)cookie;
24
24
  struct cb_bucket_st *bucket = ctx->bucket;
25
- VALUE key, res, *rv = ctx->rv;
25
+ VALUE key, res, *rv = ctx->rv, exc;
26
26
 
27
27
  if (resp->v.v0.key) {
28
28
  key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
29
- ctx->exception = cb_check_error(error, "failed to execute observe request", key);
30
- if (ctx->exception) {
31
- cb_gc_protect(bucket, ctx->exception);
29
+ exc = cb_check_error(error, "failed to execute observe request", key);
30
+ if (exc != Qnil) {
31
+ ctx->exception = cb_gc_protect(bucket, exc);
32
32
  }
33
33
  res = rb_class_new_instance(0, NULL, cb_cResult);
34
34
  rb_ivar_set(res, cb_id_iv_completed, Qfalse);
@@ -54,7 +54,7 @@ cb_observe_callback(lcb_t handle, const void *cookie, lcb_error_t error, const l
54
54
  }
55
55
  if (bucket->async) { /* asynchronous */
56
56
  if (ctx->proc != Qnil) {
57
- cb_proc_call(ctx->proc, 1, res);
57
+ cb_proc_call(bucket, ctx->proc, 1, res);
58
58
  }
59
59
  } else { /* synchronous */
60
60
  if (NIL_P(ctx->exception)) {
@@ -70,12 +70,12 @@ cb_observe_callback(lcb_t handle, const void *cookie, lcb_error_t error, const l
70
70
  if (bucket->async && ctx->proc != Qnil) {
71
71
  res = rb_class_new_instance(0, NULL, cb_cResult);
72
72
  rb_ivar_set(res, cb_id_iv_completed, Qtrue);
73
- cb_proc_call(ctx->proc, 1, res);
73
+ cb_proc_call(bucket, ctx->proc, 1, res);
74
74
  }
75
75
  ctx->nqueries--;
76
76
  cb_gc_unprotect(bucket, ctx->proc);
77
77
  if (bucket->async) {
78
- xfree(ctx);
78
+ free(ctx);
79
79
  }
80
80
  }
81
81
  (void)handle;
@@ -130,7 +130,7 @@ cb_bucket_observe(int argc, VALUE *argv, VALUE self)
130
130
  params.type = cb_cmd_observe;
131
131
  params.bucket = bucket;
132
132
  cb_params_build(&params, RARRAY_LEN(args), args);
133
- ctx = xcalloc(1, sizeof(struct cb_context_st));
133
+ ctx = calloc(1, sizeof(struct cb_context_st));
134
134
  if (ctx == NULL) {
135
135
  rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
136
136
  }
@@ -145,7 +145,7 @@ cb_bucket_observe(int argc, VALUE *argv, VALUE self)
145
145
  cb_params_destroy(&params);
146
146
  exc = cb_check_error(err, "failed to schedule observe request", Qnil);
147
147
  if (exc != Qnil) {
148
- xfree(ctx);
148
+ free(ctx);
149
149
  rb_exc_raise(exc);
150
150
  }
151
151
  bucket->nbytes += params.npayload;
@@ -158,7 +158,7 @@ cb_bucket_observe(int argc, VALUE *argv, VALUE self)
158
158
  lcb_wait(bucket->handle);
159
159
  }
160
160
  exc = ctx->exception;
161
- xfree(ctx);
161
+ free(ctx);
162
162
  if (exc != Qnil) {
163
163
  cb_gc_unprotect(bucket, exc);
164
164
  rb_exc_raise(exc);
@@ -28,9 +28,7 @@ cb_stat_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_
28
28
  exc = cb_check_error(error, "failed to fetch stats", node);
29
29
  if (exc != Qnil) {
30
30
  rb_ivar_set(exc, cb_id_iv_operation, cb_sym_stats);
31
- if (NIL_P(ctx->exception)) {
32
- ctx->exception = cb_gc_protect(bucket, exc);
33
- }
31
+ ctx->exception = cb_gc_protect(bucket, exc);
34
32
  }
35
33
  if (node != Qnil) {
36
34
  key = STR_NEW((const char*)resp->v.v0.key, resp->v.v0.nkey);
@@ -43,7 +41,7 @@ cb_stat_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_
43
41
  rb_ivar_set(res, cb_id_iv_node, node);
44
42
  rb_ivar_set(res, cb_id_iv_key, key);
45
43
  rb_ivar_set(res, cb_id_iv_value, val);
46
- cb_proc_call(ctx->proc, 1, res);
44
+ cb_proc_call(bucket, ctx->proc, 1, res);
47
45
  }
48
46
  } else { /* synchronous */
49
47
  if (NIL_P(exc)) {
@@ -58,7 +56,7 @@ cb_stat_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb_
58
56
  } else {
59
57
  cb_gc_unprotect(bucket, ctx->proc);
60
58
  if (bucket->async) {
61
- xfree(ctx);
59
+ free(ctx);
62
60
  }
63
61
  }
64
62
  (void)handle;
@@ -126,7 +124,7 @@ cb_bucket_stats(int argc, VALUE *argv, VALUE self)
126
124
  params.type = cb_cmd_stats;
127
125
  params.bucket = bucket;
128
126
  cb_params_build(&params, RARRAY_LEN(args), args);
129
- ctx = xcalloc(1, sizeof(struct cb_context_st));
127
+ ctx = calloc(1, sizeof(struct cb_context_st));
130
128
  if (ctx == NULL) {
131
129
  rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
132
130
  }
@@ -141,7 +139,7 @@ cb_bucket_stats(int argc, VALUE *argv, VALUE self)
141
139
  exc = cb_check_error(err, "failed to schedule stat request", Qnil);
142
140
  cb_params_destroy(&params);
143
141
  if (exc != Qnil) {
144
- xfree(ctx);
142
+ free(ctx);
145
143
  rb_exc_raise(exc);
146
144
  }
147
145
  bucket->nbytes += params.npayload;
@@ -154,7 +152,7 @@ cb_bucket_stats(int argc, VALUE *argv, VALUE self)
154
152
  lcb_wait(bucket->handle);
155
153
  }
156
154
  exc = ctx->exception;
157
- xfree(ctx);
155
+ free(ctx);
158
156
  if (exc != Qnil) {
159
157
  cb_gc_unprotect(bucket, exc);
160
158
  rb_exc_raise(exc);
@@ -26,14 +26,14 @@ storage_observe_callback(VALUE args, VALUE cookie)
26
26
 
27
27
  if (ctx->proc != Qnil) {
28
28
  rb_ivar_set(res, cb_id_iv_operation, ctx->operation);
29
- cb_proc_call(ctx->proc, 1, res);
29
+ cb_proc_call(bucket, ctx->proc, 1, res);
30
30
  }
31
31
  if (!RTEST(ctx->observe_options)) {
32
32
  ctx->nqueries--;
33
33
  if (ctx->nqueries == 0) {
34
34
  cb_gc_unprotect(bucket, ctx->proc);
35
35
  if (bucket->async) {
36
- xfree(ctx);
36
+ free(ctx);
37
37
  }
38
38
  }
39
39
  }
@@ -75,9 +75,7 @@ cb_storage_callback(lcb_t handle, const void *cookie, lcb_storage_t operation,
75
75
  if (exc != Qnil) {
76
76
  rb_ivar_set(exc, cb_id_iv_cas, cas);
77
77
  rb_ivar_set(exc, cb_id_iv_operation, ctx->operation);
78
- if (NIL_P(ctx->exception)) {
79
- ctx->exception = cb_gc_protect(bucket, exc);
80
- }
78
+ ctx->exception = cb_gc_protect(bucket, exc);
81
79
  }
82
80
 
83
81
  if (bucket->async) { /* asynchronous */
@@ -95,7 +93,7 @@ cb_storage_callback(lcb_t handle, const void *cookie, lcb_storage_t operation,
95
93
  rb_ivar_set(res, cb_id_iv_key, key);
96
94
  rb_ivar_set(res, cb_id_iv_operation, ctx->operation);
97
95
  rb_ivar_set(res, cb_id_iv_cas, cas);
98
- cb_proc_call(ctx->proc, 1, res);
96
+ cb_proc_call(bucket, ctx->proc, 1, res);
99
97
  }
100
98
  } else { /* synchronous */
101
99
  rb_hash_aset(*rv, key, cas);
@@ -106,7 +104,7 @@ cb_storage_callback(lcb_t handle, const void *cookie, lcb_storage_t operation,
106
104
  if (ctx->nqueries == 0) {
107
105
  cb_gc_unprotect(bucket, ctx->proc);
108
106
  if (bucket->async) {
109
- xfree(ctx);
107
+ free(ctx);
110
108
  }
111
109
  }
112
110
  }
@@ -134,7 +132,7 @@ cb_bucket_store(lcb_storage_t cmd, int argc, VALUE *argv, VALUE self)
134
132
  params.bucket = bucket;
135
133
  params.cmd.store.operation = cmd;
136
134
  cb_params_build(&params, RARRAY_LEN(args), args);
137
- ctx = xcalloc(1, sizeof(struct cb_context_st));
135
+ ctx = calloc(1, sizeof(struct cb_context_st));
138
136
  if (ctx == NULL) {
139
137
  rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
140
138
  }
@@ -150,7 +148,7 @@ cb_bucket_store(lcb_storage_t cmd, int argc, VALUE *argv, VALUE self)
150
148
  cb_params_destroy(&params);
151
149
  exc = cb_check_error(err, "failed to schedule set request", Qnil);
152
150
  if (exc != Qnil) {
153
- xfree(ctx);
151
+ free(ctx);
154
152
  rb_exc_raise(exc);
155
153
  }
156
154
  bucket->nbytes += params.npayload;
@@ -163,7 +161,7 @@ cb_bucket_store(lcb_storage_t cmd, int argc, VALUE *argv, VALUE self)
163
161
  lcb_wait(bucket->handle);
164
162
  }
165
163
  exc = ctx->exception;
166
- xfree(ctx);
164
+ free(ctx);
167
165
  if (exc != Qnil) {
168
166
  cb_gc_unprotect(bucket, exc);
169
167
  rb_exc_raise(exc);
@@ -106,7 +106,7 @@ cb_timer_cancel(VALUE self)
106
106
  trigger_timer(VALUE timer)
107
107
  {
108
108
  struct cb_timer_st *tm = DATA_PTR(timer);
109
- return cb_proc_call(tm->callback, 1, timer);
109
+ return cb_proc_call(tm->bucket, tm->callback, 1, timer);
110
110
  }
111
111
 
112
112
  static void
@@ -32,9 +32,7 @@ cb_touch_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb
32
32
  exc = cb_check_error(error, "failed to touch value", key);
33
33
  if (exc != Qnil) {
34
34
  rb_ivar_set(exc, cb_id_iv_operation, cb_sym_touch);
35
- if (NIL_P(ctx->exception)) {
36
- ctx->exception = cb_gc_protect(bucket, exc);
37
- }
35
+ ctx->exception = cb_gc_protect(bucket, exc);
38
36
  }
39
37
  }
40
38
 
@@ -44,7 +42,7 @@ cb_touch_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb
44
42
  rb_ivar_set(res, cb_id_iv_error, exc);
45
43
  rb_ivar_set(res, cb_id_iv_operation, cb_sym_touch);
46
44
  rb_ivar_set(res, cb_id_iv_key, key);
47
- cb_proc_call(ctx->proc, 1, res);
45
+ cb_proc_call(bucket, ctx->proc, 1, res);
48
46
  }
49
47
  } else { /* synchronous */
50
48
  rb_hash_aset(*rv, key, (error == LCB_SUCCESS) ? Qtrue : Qfalse);
@@ -52,7 +50,7 @@ cb_touch_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lcb
52
50
  if (ctx->nqueries == 0) {
53
51
  cb_gc_unprotect(bucket, ctx->proc);
54
52
  if (bucket->async) {
55
- xfree(ctx);
53
+ free(ctx);
56
54
  }
57
55
  }
58
56
  (void)handle;
@@ -144,7 +142,7 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
144
142
  params.type = cb_cmd_touch;
145
143
  params.bucket = bucket;
146
144
  cb_params_build(&params, RARRAY_LEN(args), args);
147
- ctx = xcalloc(1, sizeof(struct cb_context_st));
145
+ ctx = calloc(1, sizeof(struct cb_context_st));
148
146
  if (ctx == NULL) {
149
147
  rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
150
148
  }
@@ -160,7 +158,7 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
160
158
  cb_params_destroy(&params);
161
159
  exc = cb_check_error(err, "failed to schedule touch request", Qnil);
162
160
  if (exc != Qnil) {
163
- xfree(ctx);
161
+ free(ctx);
164
162
  rb_exc_raise(exc);
165
163
  }
166
164
  bucket->nbytes += params.npayload;
@@ -173,7 +171,7 @@ cb_bucket_touch(int argc, VALUE *argv, VALUE self)
173
171
  lcb_wait(bucket->handle);
174
172
  }
175
173
  exc = ctx->exception;
176
- xfree(ctx);
174
+ free(ctx);
177
175
  if (exc != Qnil) {
178
176
  rb_exc_raise(cb_gc_unprotect(bucket, exc));
179
177
  }
@@ -32,9 +32,7 @@ cb_unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lc
32
32
  exc = cb_check_error(error, "failed to unlock value", key);
33
33
  if (exc != Qnil) {
34
34
  rb_ivar_set(exc, cb_id_iv_operation, cb_sym_unlock);
35
- if (NIL_P(ctx->exception)) {
36
- ctx->exception = cb_gc_protect(bucket, exc);
37
- }
35
+ ctx->exception = cb_gc_protect(bucket, exc);
38
36
  }
39
37
  }
40
38
 
@@ -44,7 +42,7 @@ cb_unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lc
44
42
  rb_ivar_set(res, cb_id_iv_error, exc);
45
43
  rb_ivar_set(res, cb_id_iv_operation, cb_sym_unlock);
46
44
  rb_ivar_set(res, cb_id_iv_key, key);
47
- cb_proc_call(ctx->proc, 1, res);
45
+ cb_proc_call(bucket, ctx->proc, 1, res);
48
46
  }
49
47
  } else { /* synchronous */
50
48
  rb_hash_aset(*rv, key, (error == LCB_SUCCESS) ? Qtrue : Qfalse);
@@ -52,7 +50,7 @@ cb_unlock_callback(lcb_t handle, const void *cookie, lcb_error_t error, const lc
52
50
  if (ctx->nqueries == 0) {
53
51
  cb_gc_unprotect(bucket, ctx->proc);
54
52
  if (bucket->async) {
55
- xfree(ctx);
53
+ free(ctx);
56
54
  }
57
55
  }
58
56
  (void)handle;
@@ -134,7 +132,7 @@ cb_bucket_unlock(int argc, VALUE *argv, VALUE self)
134
132
  params.type = cb_cmd_unlock;
135
133
  params.bucket = bucket;
136
134
  cb_params_build(&params, RARRAY_LEN(args), args);
137
- ctx = xcalloc(1, sizeof(struct cb_context_st));
135
+ ctx = calloc(1, sizeof(struct cb_context_st));
138
136
  if (ctx == NULL) {
139
137
  rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
140
138
  }
@@ -150,7 +148,7 @@ cb_bucket_unlock(int argc, VALUE *argv, VALUE self)
150
148
  cb_params_destroy(&params);
151
149
  exc = cb_check_error(err, "failed to schedule unlock request", Qnil);
152
150
  if (exc != Qnil) {
153
- xfree(ctx);
151
+ free(ctx);
154
152
  rb_exc_raise(exc);
155
153
  }
156
154
  bucket->nbytes += params.npayload;
@@ -163,7 +161,7 @@ cb_bucket_unlock(int argc, VALUE *argv, VALUE self)
163
161
  lcb_wait(bucket->handle);
164
162
  }
165
163
  exc = ctx->exception;
166
- xfree(ctx);
164
+ free(ctx);
167
165
  if (exc != Qnil) {
168
166
  rb_exc_raise(cb_gc_unprotect(bucket, exc));
169
167
  }
@@ -31,13 +31,65 @@ cb_gc_unprotect(struct cb_bucket_st *bucket, VALUE val)
31
31
  return val;
32
32
  }
33
33
 
34
+ struct proc_params_st
35
+ {
36
+ struct cb_bucket_st *bucket;
37
+ VALUE recv;
38
+ ID mid;
39
+ int argc;
40
+ VALUE *argv;
41
+ VALUE exc;
42
+ };
43
+
44
+ static VALUE
45
+ do_async_error_notify(VALUE ptr)
46
+ {
47
+ struct proc_params_st *p = (struct proc_params_st *)ptr;
48
+ return rb_funcall(p->bucket->on_error_proc, cb_id_call, 1, p->exc);
49
+ }
50
+
51
+ void
52
+ cb_async_error_notify(struct cb_bucket_st *bucket, VALUE exc)
53
+ {
54
+ if (bucket->on_error_proc != Qnil) {
55
+ struct proc_params_st params;
56
+ int fail;
57
+ params.bucket = bucket;
58
+ params.exc = exc;
59
+ rb_protect(do_async_error_notify, (VALUE)&params, &fail);
60
+ if (fail) {
61
+ rb_warning("Couchbase::Bucket#on_error shouldn't raise exceptions");
62
+ }
63
+ } else {
64
+ if (NIL_P(bucket->exception)) {
65
+ bucket->exception = exc;
66
+ }
67
+ }
68
+ }
69
+
70
+ static VALUE
71
+ func_call_failed(VALUE ptr, VALUE exc)
72
+ {
73
+ struct proc_params_st *p = (struct proc_params_st *)ptr;
74
+ cb_async_error_notify(p->bucket, exc);
75
+ return Qnil;
76
+ }
77
+
78
+ static VALUE
79
+ do_func_call(VALUE ptr)
80
+ {
81
+ struct proc_params_st *p = (struct proc_params_st *)ptr;
82
+ return rb_funcall2(p->recv, p->mid, p->argc, p->argv);
83
+ }
84
+
34
85
  VALUE
35
- cb_proc_call(VALUE recv, int argc, ...)
86
+ cb_proc_call(struct cb_bucket_st *bucket, VALUE recv, int argc, ...)
36
87
  {
37
88
  VALUE *argv;
38
89
  va_list ar;
39
90
  int arity;
40
91
  int ii;
92
+ struct proc_params_st params;
41
93
 
42
94
  arity = FIX2INT(rb_funcall(recv, cb_id_arity, 0));
43
95
  if (arity < 0) {
@@ -57,7 +109,14 @@ cb_proc_call(VALUE recv, int argc, ...)
57
109
  } else {
58
110
  argv = NULL;
59
111
  }
60
- return rb_funcall2(recv, cb_id_call, arity, argv);
112
+ params.bucket = bucket;
113
+ params.recv = recv;
114
+ params.mid = cb_id_call;
115
+ params.argc = arity;
116
+ params.argv = argv;
117
+ return rb_rescue2(do_func_call, (VALUE)&params,
118
+ func_call_failed, (VALUE)&params,
119
+ rb_eException, (VALUE)0);
61
120
  }
62
121
 
63
122
  VALUE
@@ -408,8 +467,8 @@ cb_decode_value(VALUE blob, uint32_t flags, VALUE force_format)
408
467
  void
409
468
  cb_strip_key_prefix(struct cb_bucket_st *bucket, VALUE key)
410
469
  {
411
- if (bucket->key_prefix) {
412
- rb_str_update(key, 0, RSTRING_LEN(bucket->key_prefix_val), STR_NEW_CSTR(""));
470
+ if (RTEST(bucket->key_prefix_val)) {
471
+ rb_str_update(key, 0, RSTRING_LEN(bucket->key_prefix_val), cb_vStrEmpty);
413
472
  }
414
473
  }
415
474
 
@@ -418,7 +477,7 @@ cb_unify_key(struct cb_bucket_st *bucket, VALUE key, int apply_prefix)
418
477
  {
419
478
  VALUE ret = Qnil, tmp;
420
479
 
421
- if (bucket->key_prefix && apply_prefix) {
480
+ if (RTEST(bucket->key_prefix_val) && apply_prefix) {
422
481
  ret = rb_str_dup(bucket->key_prefix_val);
423
482
  }
424
483
  switch (TYPE(key)) {
@@ -476,3 +535,14 @@ cb_first_value_i(VALUE key, VALUE value, VALUE arg)
476
535
  (void)key;
477
536
  return ST_STOP;
478
537
  }
538
+
539
+ #ifndef HAVE_RB_HASH_LOOKUP2
540
+ VALUE
541
+ rb_hash_lookup2(VALUE hash, VALUE key, VALUE dflt)
542
+ {
543
+ if (RTEST(rb_funcall2(hash, cb_id_has_key_p, 1, &key))) {
544
+ dflt = rb_hash_aref(hash, key);
545
+ }
546
+ return dflt;
547
+ }
548
+ #endif
@@ -28,9 +28,7 @@ cb_version_callback(lcb_t handle, const void *cookie, lcb_error_t error, const l
28
28
  exc = cb_check_error(error, "failed to get version", node);
29
29
  if (exc != Qnil) {
30
30
  rb_ivar_set(exc, cb_id_iv_operation, cb_sym_version);
31
- if (NIL_P(ctx->exception)) {
32
- ctx->exception = cb_gc_protect(bucket, exc);
33
- }
31
+ ctx->exception = cb_gc_protect(bucket, exc);
34
32
  }
35
33
 
36
34
  if (node != Qnil) {
@@ -42,7 +40,7 @@ cb_version_callback(lcb_t handle, const void *cookie, lcb_error_t error, const l
42
40
  rb_ivar_set(res, cb_id_iv_operation, cb_sym_version);
43
41
  rb_ivar_set(res, cb_id_iv_node, node);
44
42
  rb_ivar_set(res, cb_id_iv_value, val);
45
- cb_proc_call(ctx->proc, 1, res);
43
+ cb_proc_call(bucket, ctx->proc, 1, res);
46
44
  }
47
45
  } else { /* synchronous */
48
46
  if (NIL_P(exc)) {
@@ -53,7 +51,7 @@ cb_version_callback(lcb_t handle, const void *cookie, lcb_error_t error, const l
53
51
  ctx->nqueries--;
54
52
  cb_gc_unprotect(bucket, ctx->proc);
55
53
  if (bucket->async) {
56
- xfree(ctx);
54
+ free(ctx);
57
55
  }
58
56
  }
59
57
 
@@ -107,7 +105,7 @@ cb_bucket_version(int argc, VALUE *argv, VALUE self)
107
105
  params.type = cb_cmd_version;
108
106
  params.bucket = bucket;
109
107
  cb_params_build(&params, RARRAY_LEN(args), args);
110
- ctx = xcalloc(1, sizeof(struct cb_context_st));
108
+ ctx = calloc(1, sizeof(struct cb_context_st));
111
109
  if (ctx == NULL) {
112
110
  rb_raise(cb_eClientNoMemoryError, "failed to allocate memory for context");
113
111
  }
@@ -122,7 +120,7 @@ cb_bucket_version(int argc, VALUE *argv, VALUE self)
122
120
  exc = cb_check_error(err, "failed to schedule version request", Qnil);
123
121
  cb_params_destroy(&params);
124
122
  if (exc != Qnil) {
125
- xfree(ctx);
123
+ free(ctx);
126
124
  rb_exc_raise(exc);
127
125
  }
128
126
  bucket->nbytes += params.npayload;
@@ -135,7 +133,7 @@ cb_bucket_version(int argc, VALUE *argv, VALUE self)
135
133
  lcb_wait(bucket->handle);
136
134
  }
137
135
  exc = ctx->exception;
138
- xfree(ctx);
136
+ free(ctx);
139
137
  if (exc != Qnil) {
140
138
  cb_gc_unprotect(bucket, exc);
141
139
  rb_exc_raise(exc);