+static int log_level = 0;
+static int log_level_initialized = 0;
+
+/** \fn rfd_create_base(RSET rs)
+ *
+ * creates an rfd. Either allocates a new one, in which case the priv
+ * pointer is null, and will have to be filled in, or picks up one
+ * from the freelist, in which case the priv is already allocated,
+ * and presumably everything that hangs from it as well
+ */
+RSFD rfd_create_base(RSET rs)
+{
+ RSFD rnew = rs->free_list;
+
+ if (rnew)
+ {
+ rs->free_list = rnew->next;
+ assert(rnew->rset==rs);
+ yaz_log(log_level, "rfd_create_base (fl): rfd=%p rs=%p fl=%p priv=%p",
+ rnew, rs, rs->free_list, rnew->priv);
+ }
+ else
+ {
+ rnew = nmem_malloc(rs->nmem, sizeof(*rnew));
+ rnew->priv = NULL;
+ rnew->rset = rs;
+ yaz_log(log_level, "rfd_create_base (new): rfd=%p rs=%p fl=%p priv=%p",
+ rnew, rs, rs->free_list, rnew->priv);
+ }
+ rnew->next = rs->use_list;
+ rs->use_list = rnew;
+ return rnew;
+}
+
+/** \fn rfd_delete_base
+ *
+ * puts an rfd into the freelist of the rset. Only when the rset gets
+ * deleted, will all the nmem disappear */
+void rfd_delete_base(RSFD rfd)
+{
+ RSFD *pfd;
+ RSET rs = rfd->rset;
+ yaz_log(log_level, "rfd_delete_base: rfd=%p rs=%p priv=%p fl=%p",
+ rfd, rs, rfd->priv, rs->free_list);
+ for (pfd = &rs->use_list; *pfd; pfd = &(*pfd)->next)
+ if (*pfd == rfd)
+ {
+ *pfd = (*pfd)->next;
+ rfd->next = rs->free_list;
+ rs->free_list = rfd;
+ return;
+ }
+ yaz_log(YLOG_WARN, "rset_close handle not found. type=%s",
+ rs->control->desc);
+}
+
+RSET rset_create_base(const struct rset_control *sel,
+ NMEM nmem, const struct key_control *kcontrol,
+ int scope, TERMID term)