+
+typedef struct rbl_context_t {
+ rbl_result_t *result;
+ rbl_result_callback_t call;
+ void *data;
+} rbl_context_t;
+ARRAY(rbl_context_t);
+
+static struct ub_ctx *ctx = NULL;
+static PA(rbl_context_t) ctx_pool = ARRAY_INIT;
+
+static rbl_context_t *rbl_context_new(void)
+{
+ return p_new(rbl_context_t, 1);
+}
+
+static void rbl_context_delete(rbl_context_t **context)
+{
+ if (*context) {
+ p_delete(context);
+ }
+}
+
+static void rbl_context_wipe(rbl_context_t *context)
+{
+ p_clear(context, 1);
+}
+
+static rbl_context_t *rbl_context_acquire(void)
+{
+ if (array_len(ctx_pool) > 0) {
+ return array_pop_last(ctx_pool);
+ } else {
+ return rbl_context_new();
+ }
+}
+
+static void rbl_context_release(rbl_context_t *context)
+{
+ rbl_context_wipe(context);
+ array_add(ctx_pool, context);
+}
+
+static void rbl_exit(void)
+{
+ if (ctx != NULL) {
+ ub_ctx_delete(ctx);
+ ctx = NULL;
+ }
+ array_deep_wipe(ctx_pool, rbl_context_delete);
+}
+module_exit(rbl_exit);
+
+static void rbl_callback(void *arg, int err, struct ub_result *result)