mod_netconf: hopefuly "stable" version

- refactoring
- locking strategy revision
diff --git a/src/mod_netconf.c b/src/mod_netconf.c
index 1bc0390..b1c8555 100644
--- a/src/mod_netconf.c
+++ b/src/mod_netconf.c
@@ -106,7 +106,8 @@
 
 module AP_MODULE_DECLARE_DATA netconf_module;
 
-pthread_rwlock_t session_lock; /**< mutex protecting netconf_session_list from multiple access errors */
+pthread_rwlock_t session_lock; /**< mutex protecting netconf_sessions_list from multiple access errors */
+apr_hash_t *netconf_sessions_list = NULL;
 
 volatile int isterminated = 0;
 
@@ -206,6 +207,9 @@
 	if (sid) json_object_object_add(err_reply, "session-id", json_object_new_string(sid));
 }
 
+/**
+ * should be used in locked area
+ */
 void prepare_status_message(server_rec* server, struct session_with_mutex *s, struct nc_session *session)
 {
 	json_object *json_obj = NULL;
@@ -270,7 +274,7 @@
  *
  * \warning Session_key hash is not bound with caller identification. This could be potential security risk.
  */
-static char* netconf_connect(server_rec* server, apr_pool_t* pool, apr_hash_t* conns, const char* host, const char* port, const char* user, const char* pass, struct nc_cpblts * cpblts)
+static char* netconf_connect(server_rec* server, apr_pool_t* pool, const char* host, const char* port, const char* user, const char* pass, struct nc_cpblts * cpblts)
 {
 	struct nc_session* session = NULL;
 	struct session_with_mutex * locked_session;
@@ -308,23 +312,28 @@
 		if (pthread_rwlock_wrlock (&session_lock) != 0) {
 			nc_session_free(session);
 			free (locked_session);
-			ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
 			return NULL;
 		}
 		locked_session->notifications = apr_array_make(pool, NOTIFICATION_QUEUE_SIZE, sizeof(notification_t));
 		locked_session->ntfc_subscribed = 0;
 		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "Add connection to the list");
-		apr_hash_set(conns, apr_pstrdup(pool, session_key), APR_HASH_KEY_STRING, (void *) locked_session);
+		apr_hash_set(netconf_sessions_list, apr_pstrdup(pool, session_key), APR_HASH_KEY_STRING, (void *) locked_session);
 		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "Before session_unlock");
 
+		/* lock session */
+		pthread_mutex_lock(&locked_session->lock);
+
+		/* unlock session list */
+		if (pthread_rwlock_unlock (&session_lock) != 0) {
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		}
+
 		/* store information about session from hello message for future usage */
 		prepare_status_message(server, locked_session, session);
 
-		/* end of critical section */
-		if (pthread_rwlock_unlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
-			return NULL;
-		}
+		pthread_mutex_unlock(&locked_session->lock);
+
 		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "NETCONF session established");
 		return (session_key);
 	} else {
@@ -334,85 +343,72 @@
 
 }
 
-static int netconf_close(server_rec* server, apr_hash_t* conns, const char* session_key)
+static int close_and_free_session(server_rec *server, struct session_with_mutex *locked_session)
 {
-	struct nc_session *ns = NULL;
+	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "lock private lock.");
+	if (pthread_mutex_lock(&locked_session->lock) != 0) {
+		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock");
+	}
+	locked_session->ntfc_subscribed = 0;
+	locked_session->closed = 1;
+	nc_session_close(locked_session->session, NC_SESSION_TERM_CLOSED);
+	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "session closed.");
+	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "unlock private lock.");
+	if (pthread_mutex_unlock(&locked_session->lock) != 0) {
+		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock");
+	}
+
+	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "unlock session lock.");
+	ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "closed session, disabled notif(?), wait 2s");
+	usleep(500000); /* let notification thread stop */
+
+	/* session shouldn't be used by now */
+	/** \todo free all notifications from queue */
+	apr_array_clear(locked_session->notifications);
+	pthread_mutex_destroy(&locked_session->lock);
+	if (locked_session->hello_message != NULL) {
+		/** \todo free hello_message */
+		//json_object_put(locked_session->hello_message);
+		locked_session->hello_message = NULL;
+	}
+	nc_session_free(locked_session->session);
+	locked_session->session = NULL;
+	free (locked_session);
+	locked_session = NULL;
+	ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "NETCONF session closed, everything cleared.");
+	return (EXIT_SUCCESS);
+}
+
+static int netconf_close(server_rec* server, const char* session_key)
+{
 	struct session_with_mutex * locked_session;
 
 	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Key in hash to close: %s", session_key);
+
 	/* get exclusive (write) access to sessions_list (conns) */
 	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "lock session lock.");
 	if (pthread_rwlock_wrlock (&session_lock) != 0) {
-		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
+		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock");
 		return EXIT_FAILURE;
 	}
-	locked_session = (struct session_with_mutex *)apr_hash_get(conns, session_key, APR_HASH_KEY_STRING);
-	if (locked_session != NULL) {
-		/** \todo free all notifications from queue */
-		ns = locked_session->session;
-	}
-	if (ns != NULL) {
-		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "lock private lock.");
-		if (pthread_mutex_lock(&locked_session->lock) != 0) {
-			ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
-			return EXIT_FAILURE;
-		}
-		locked_session->ntfc_subscribed = 0;
-		locked_session->closed = 1;
-		nc_session_close (ns, NC_SESSION_TERM_CLOSED);
-		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "session closed.");
-		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "unlock private lock.");
-		if (pthread_mutex_unlock(&locked_session->lock) != 0) {
-			ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
-			return EXIT_FAILURE;
-		}
-		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "unlock session lock.");
-		if (pthread_rwlock_unlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
-			return EXIT_FAILURE;
-		}
-		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "closed session, disabled notif(?), wait 2s");
-		sleep(2); /* let notification thread stop */
-		/* remove session from the active sessions list */
-		apr_hash_set(conns, session_key, APR_HASH_KEY_STRING, NULL);
-		/* end of critical section */
+	/* get session to close */
+	locked_session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
+	/* remove session from the active sessions list -> nobody new can now work with session */
+	apr_hash_set(netconf_sessions_list, session_key, APR_HASH_KEY_STRING, NULL);
 
-		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "lock session lock.");
-		if (pthread_rwlock_wrlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
-			return EXIT_FAILURE;
-		}
-		/** \todo free all notifications from queue */
-		apr_array_clear(locked_session->notifications);
-		pthread_mutex_destroy(&locked_session->lock);
-		ns = locked_session->session;
-		if (locked_session->hello_message != NULL) {
-			json_object_put(locked_session->hello_message);
-			locked_session->hello_message = NULL;
-		}
-		nc_session_free(ns);
-		ns = NULL;
-		free (locked_session);
-		locked_session = NULL;
-		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "unlock session lock.");
-		if (pthread_rwlock_unlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
-			return EXIT_FAILURE;
-		}
-		ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, server, "NETCONF session closed, everything cleared.");
-		return (EXIT_SUCCESS);
+	if (pthread_rwlock_unlock (&session_lock) != 0) {
+		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock");
+	}
+
+	if ((locked_session != NULL) && (locked_session->session != NULL)) {
+		return close_and_free_session(server, locked_session);
 	} else {
-		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "unlock session lock.");
-		if (pthread_rwlock_unlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
-			return EXIT_FAILURE;
-		}
 		ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "Unknown session to close");
 		return (EXIT_FAILURE);
 	}
 }
 
-static int netconf_op(server_rec* server, apr_hash_t* conns, const char* session_key, nc_rpc* rpc)
+int netconf_op(server_rec* server, const char* session_key, nc_rpc* rpc)
 {
 	struct nc_session *session = NULL;
 	struct session_with_mutex * locked_session;
@@ -429,11 +425,11 @@
 
 	/* get non-exclusive (read) access to sessions_list (conns) */
 	if (pthread_rwlock_rdlock (&session_lock) != 0) {
-		ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
+		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
 		return EXIT_FAILURE;
 	}
 	/* get session where send the RPC */
-	locked_session = (struct session_with_mutex *)apr_hash_get(conns, session_key, APR_HASH_KEY_STRING);
+	locked_session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
 	if (locked_session != NULL) {
 		session = locked_session->session;
 	}
@@ -442,11 +438,15 @@
 		if (pthread_mutex_lock(&locked_session->lock) != 0) {
 			/* unlock before returning error */
 			if (pthread_rwlock_unlock (&session_lock) != 0) {
-				ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
+				ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
 				return EXIT_FAILURE;
 			}
 			return EXIT_FAILURE;
 		}
+		if (pthread_rwlock_unlock(&session_lock) != 0) {
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
+		}
+
 		locked_session->last_activity = apr_time_now();
 		/* send the request and get the reply */
 		msgt = nc_session_send_recv(session, rpc, &reply);
@@ -454,17 +454,13 @@
 		/* first release exclusive lock for this session */
 		pthread_mutex_unlock(&locked_session->lock);
 		/* end of critical section */
-		if (pthread_rwlock_unlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
-			return EXIT_FAILURE;
-		}
 
 		/* process the result of the operation */
 		switch (msgt) {
 		case NC_MSG_UNKNOWN:
 			if (nc_session_get_status(session) != NC_SESSION_STATUS_WORKING) {
 				ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "mod_netconf: receiving rpc-reply failed");
-				netconf_close(server, conns, session_key);
+				netconf_close(server, session_key);
 				return (EXIT_FAILURE);
 			}
 			/* no break */
@@ -493,14 +489,14 @@
 	} else {
 		/* release lock on failure */
 		if (pthread_rwlock_unlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
 		}
 		ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "Unknown session to process.");
 		return (EXIT_FAILURE);
 	}
 }
 
-static char* netconf_opdata(server_rec* server, apr_hash_t* conns, const char* session_key, nc_rpc* rpc)
+static char* netconf_opdata(server_rec* server, const char* session_key, nc_rpc* rpc)
 {
 	struct nc_session *session = NULL;
 	struct session_with_mutex * locked_session;
@@ -517,11 +513,11 @@
 
 	/* get non-exclusive (read) access to sessions_list (conns) */
 	if (pthread_rwlock_rdlock (&session_lock) != 0) {
-		ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
+		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
 		return NULL;
 	}
 	/* get session where send the RPC */
-	locked_session = (struct session_with_mutex *)apr_hash_get(conns, session_key, APR_HASH_KEY_STRING);
+	locked_session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
 	if (locked_session != NULL) {
 		session = locked_session->session;
 	}
@@ -530,29 +526,26 @@
 		if (pthread_mutex_lock(&locked_session->lock) != 0) {
 			/* unlock before returning error */
 			if (pthread_rwlock_unlock (&session_lock) != 0) {
-				ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
-				return NULL;
+				ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", errno, strerror(errno));
 			}
 			return NULL;
 		}
+		if (pthread_rwlock_unlock (&session_lock) != 0) {
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		}
 		locked_session->last_activity = apr_time_now();
 		/* send the request and get the reply */
 		msgt = nc_session_send_recv(session, rpc, &reply);
 
 		/* first release exclusive lock for this session */
 		pthread_mutex_unlock(&locked_session->lock);
-		/* end of critical section */
-		if (pthread_rwlock_unlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
-			return (NULL);
-		}
 
 		/* process the result of the operation */
 		switch (msgt) {
 		case NC_MSG_UNKNOWN:
 			if (nc_session_get_status(session) != NC_SESSION_STATUS_WORKING) {
 				ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "mod_netconf: receiving rpc-reply failed");
-				netconf_close(server, conns, session_key);
+				netconf_close(server, session_key);
 				return (NULL);
 			}
 			/* no break */
@@ -584,14 +577,14 @@
 	} else {
 		/* release lock on failure */
 		if (pthread_rwlock_unlock (&session_lock) != 0) {
-			ap_log_error (APLOG_MARK, APLOG_ERR, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
 		}
 		ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "Unknown session to process.");
 		return (NULL);
 	}
 }
 
-static char* netconf_getconfig(server_rec* server, apr_hash_t* conns, const char* session_key, NC_DATASTORE source, const char* filter)
+static char* netconf_getconfig(server_rec* server, const char* session_key, NC_DATASTORE source, const char* filter)
 {
 	nc_rpc* rpc;
 	struct nc_filter *f = NULL;
@@ -610,12 +603,12 @@
 		return (NULL);
 	}
 
-	data = netconf_opdata(server, conns, session_key, rpc);
+	data = netconf_opdata(server, session_key, rpc);
 	nc_rpc_free (rpc);
 	return (data);
 }
 
-static char* netconf_getschema(server_rec* server, apr_hash_t* conns, const char* session_key, const char* identifier, const char* version, const char* format)
+static char* netconf_getschema(server_rec* server, const char* session_key, const char* identifier, const char* version, const char* format)
 {
 	nc_rpc* rpc;
 	char* data = NULL;
@@ -627,12 +620,12 @@
 		return (NULL);
 	}
 
-	data = netconf_opdata(server, conns, session_key, rpc);
+	data = netconf_opdata(server, session_key, rpc);
 	nc_rpc_free (rpc);
 	return (data);
 }
 
-static char* netconf_get(server_rec* server, apr_hash_t* conns, const char* session_key, const char* filter)
+static char* netconf_get(server_rec* server, const char* session_key, const char* filter)
 {
 	nc_rpc* rpc;
 	struct nc_filter *f = NULL;
@@ -651,12 +644,12 @@
 		return (NULL);
 	}
 
-	data = netconf_opdata(server, conns, session_key, rpc);
+	data = netconf_opdata(server, session_key, rpc);
 	nc_rpc_free (rpc);
 	return (data);
 }
 
-static int netconf_copyconfig(server_rec* server, apr_hash_t* conns, const char* session_key, NC_DATASTORE source, NC_DATASTORE target, const char* config, const char *url)
+static int netconf_copyconfig(server_rec* server, const char* session_key, NC_DATASTORE source, NC_DATASTORE target, const char* config, const char *url)
 {
 	nc_rpc* rpc;
 	int retval = EXIT_SUCCESS;
@@ -680,12 +673,12 @@
 		return (EXIT_FAILURE);
 	}
 
-	retval = netconf_op(server, conns, session_key, rpc);
+	retval = netconf_op(server, session_key, rpc);
 	nc_rpc_free (rpc);
 	return (retval);
 }
 
-static int netconf_editconfig(server_rec* server, apr_hash_t* conns, const char* session_key, NC_DATASTORE target, NC_EDIT_DEFOP_TYPE defop, NC_EDIT_ERROPT_TYPE erropt, NC_EDIT_TESTOPT_TYPE testopt, const char* config)
+static int netconf_editconfig(server_rec* server, const char* session_key, NC_DATASTORE target, NC_EDIT_DEFOP_TYPE defop, NC_EDIT_ERROPT_TYPE erropt, NC_EDIT_TESTOPT_TYPE testopt, const char* config)
 {
 	nc_rpc* rpc;
 	int retval = EXIT_SUCCESS;
@@ -698,12 +691,12 @@
 		return (EXIT_FAILURE);
 	}
 
-	retval = netconf_op(server, conns, session_key, rpc);
+	retval = netconf_op(server, session_key, rpc);
 	nc_rpc_free (rpc);
 	return (retval);
 }
 
-static int netconf_killsession(server_rec* server, apr_hash_t* conns, const char* session_key, const char* sid)
+static int netconf_killsession(server_rec* server, const char* session_key, const char* sid)
 {
 	nc_rpc* rpc;
 	int retval = EXIT_SUCCESS;
@@ -715,12 +708,12 @@
 		return (EXIT_FAILURE);
 	}
 
-	retval = netconf_op(server, conns, session_key, rpc);
+	retval = netconf_op(server, session_key, rpc);
 	nc_rpc_free (rpc);
 	return (retval);
 }
 
-static int netconf_onlytargetop(server_rec* server, apr_hash_t* conns, const char* session_key, NC_DATASTORE target, nc_rpc* (*op_func)(NC_DATASTORE))
+static int netconf_onlytargetop(server_rec* server, const char* session_key, NC_DATASTORE target, nc_rpc* (*op_func)(NC_DATASTORE))
 {
 	nc_rpc* rpc;
 	int retval = EXIT_SUCCESS;
@@ -732,12 +725,12 @@
 		return (EXIT_FAILURE);
 	}
 
-	retval = netconf_op(server, conns, session_key, rpc);
+	retval = netconf_op(server, session_key, rpc);
 	nc_rpc_free (rpc);
 	return (retval);
 }
 
-static int netconf_deleteconfig(server_rec* server, apr_hash_t* conns, const char* session_key, NC_DATASTORE target)
+static int netconf_deleteconfig(server_rec* server, const char* session_key, NC_DATASTORE target)
 {
 	nc_rpc *rpc = NULL;
 	if (target != NC_DATASTORE_URL) {
@@ -748,17 +741,17 @@
 		return (EXIT_FAILURE);
 	}
 
-	return netconf_op(server, conns, session_key, rpc);
+	return netconf_op(server, session_key, rpc);
 }
 
-static int netconf_lock(server_rec* server, apr_hash_t* conns, const char* session_key, NC_DATASTORE target)
+static int netconf_lock(server_rec* server, const char* session_key, NC_DATASTORE target)
 {
-	return (netconf_onlytargetop(server, conns, session_key, target, nc_rpc_lock));
+	return (netconf_onlytargetop(server, session_key, target, nc_rpc_lock));
 }
 
-static int netconf_unlock(server_rec* server, apr_hash_t* conns, const char* session_key, NC_DATASTORE target)
+static int netconf_unlock(server_rec* server, const char* session_key, NC_DATASTORE target)
 {
-	return (netconf_onlytargetop(server, conns, session_key, target, nc_rpc_unlock));
+	return (netconf_onlytargetop(server, session_key, target, nc_rpc_unlock));
 }
 
 /**
@@ -766,9 +759,9 @@
  *         REPLY_DATA: 0, *data != NULL
  *         REPLY_ERROR: 1, *data == NULL
  */
-static int netconf_generic(server_rec* server, apr_hash_t* conns, const char* session_key, const char* content, char** data)
+static int netconf_generic(server_rec* server, const char* session_key, const char* content, char** data)
 {
-	struct nc_session *session = NULL;
+	struct session_with_mutex *session = NULL;
 	nc_reply* reply = NULL;
 	nc_rpc* rpc = NULL;
 	int retval = EXIT_SUCCESS;
@@ -786,19 +779,28 @@
 		*data = NULL;
 	}
 
+	if (pthread_rwlock_rdlock(&session_lock) != 0) {
+		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		return EXIT_FAILURE;
+	}
 	/* get session where send the RPC */
-	session = (struct nc_session *)apr_hash_get(conns, session_key, APR_HASH_KEY_STRING);
+	session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
 	if (session != NULL) {
+		pthread_mutex_lock(&session->lock);
+		if (pthread_rwlock_unlock(&session_lock) != 0) {
+			ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		}
 		/* send the request and get the reply */
-		msgt = nc_session_send_recv(session, rpc, &reply);
-		nc_rpc_free (rpc);
+		msgt = nc_session_send_recv(session->session, rpc, &reply);
+		nc_rpc_free(rpc);
+		pthread_mutex_unlock(&session->lock);
 
 		/* process the result of the operation */
 		switch (msgt) {
 		case NC_MSG_UNKNOWN:
-			if (nc_session_get_status(session) != NC_SESSION_STATUS_WORKING) {
+			if (nc_session_get_status(session->session) != NC_SESSION_STATUS_WORKING) {
 				ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "mod_netconf: receiving rpc-reply failed");
-				netconf_close(server, conns, session_key);
+				netconf_close(server, session_key);
 				return (EXIT_FAILURE);
 			}
 			/* no break */
@@ -835,6 +837,10 @@
 		return (retval);
 	} else {
 		ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "Unknown session to process.");
+		if (pthread_rwlock_unlock(&session_lock) != 0) {
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+			return EXIT_FAILURE;
+		}
 		return (EXIT_FAILURE);
 	}
 }
@@ -975,7 +981,7 @@
 	return reply;
 }
 
-json_object *handle_op_connect(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list)
+json_object *handle_op_connect(server_rec *server, apr_pool_t *pool, json_object *request)
 {
 	const char *host = NULL;
 	const char *port = NULL;
@@ -1008,7 +1014,7 @@
 		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Cannot connect - insufficient input.");
 		session_key_hash = NULL;
 	} else {
-		session_key_hash = netconf_connect(server, pool, netconf_sessions_list, host, port, user, pass, cpblts);
+		session_key_hash = netconf_connect(server, pool, host, port, user, pass, cpblts);
 		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "hash: %s", session_key_hash);
 	}
 	if (cpblts != NULL) {
@@ -1038,7 +1044,7 @@
 	return reply;
 }
 
-json_object *handle_op_get(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_get(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	const char *filter = NULL;
 	const char *data = NULL;
@@ -1048,7 +1054,7 @@
 
 	filter = json_object_get_string(json_object_object_get(request, "filter"));
 
-	if ((data = netconf_get(server, netconf_sessions_list, session_key, filter)) == NULL) {
+	if ((data = netconf_get(server, session_key, filter)) == NULL) {
 		if (err_reply == NULL) {
 			reply = create_error("Get information from device failed.");
 		} else {
@@ -1061,7 +1067,7 @@
 	return reply;
 }
 
-json_object *handle_op_getconfig(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_getconfig(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	NC_DATASTORE ds_type_s = -1;
 	NC_DATASTORE ds_type_t = -1;
@@ -1086,7 +1092,7 @@
 		return create_error("Invalid source repository type requested.");
 	}
 
-	if ((data = netconf_getconfig(server, netconf_sessions_list, session_key, ds_type_s, filter)) == NULL) {
+	if ((data = netconf_getconfig(server, session_key, ds_type_s, filter)) == NULL) {
 		if (err_reply == NULL) {
 			reply = create_error("Get configuration information from device failed.");
 		} else {
@@ -1099,7 +1105,7 @@
 	return reply;
 }
 
-json_object *handle_op_getschema(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_getschema(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	const char *data = NULL;
 	const char *identifier = NULL;
@@ -1116,7 +1122,7 @@
 	format = json_object_get_string(json_object_object_get(request, "format"));
 
 	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "get-schema(version: %s, format: %s)", version, format);
-	if ((data = netconf_getschema(server, netconf_sessions_list, session_key, identifier, version, format)) == NULL) {
+	if ((data = netconf_getschema(server, session_key, identifier, version, format)) == NULL) {
 		if (err_reply == NULL) {
 			reply = create_error("Get schema failed.");
 		} else {
@@ -1129,7 +1135,7 @@
 	return reply;
 }
 
-json_object *handle_op_editconfig(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_editconfig(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	NC_DATASTORE ds_type_s = -1;
 	NC_DATASTORE ds_type_t = -1;
@@ -1190,7 +1196,7 @@
 		return create_error("Invalid config data parameter.");
 	}
 
-	if (netconf_editconfig(server, netconf_sessions_list, session_key, ds_type_t, defop_type, erropt_type, NC_EDIT_TESTOPT_NOTSET, config) != EXIT_SUCCESS) {
+	if (netconf_editconfig(server, session_key, ds_type_t, defop_type, erropt_type, NC_EDIT_TESTOPT_NOTSET, config) != EXIT_SUCCESS) {
 		if (err_reply == NULL) {
 			reply = create_error("Edit-config failed.");
 		} else {
@@ -1204,7 +1210,7 @@
 	return reply;
 }
 
-json_object *handle_op_copyconfig(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_copyconfig(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	NC_DATASTORE ds_type_s = -1;
 	NC_DATASTORE ds_type_t = -1;
@@ -1239,7 +1245,7 @@
 	if (source == NULL && config == NULL) {
 		reply = create_error("invalid input parameters - one of source and config is required.");
 	} else {
-		if (netconf_copyconfig(server, netconf_sessions_list, session_key, ds_type_s, ds_type_t, config, "") != EXIT_SUCCESS) {
+		if (netconf_copyconfig(server, session_key, ds_type_s, ds_type_t, config, "") != EXIT_SUCCESS) {
 			if (err_reply == NULL) {
 				reply = create_error("Copying of configuration failed.");
 			} else {
@@ -1254,7 +1260,7 @@
 	return reply;
 }
 
-json_object *handle_op_generic(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_generic(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	json_object *reply = NULL;
 	const char *config = NULL;
@@ -1268,7 +1274,7 @@
 		return create_error("Missing content parameter.");
 	}
 
-	if (netconf_generic(server, netconf_sessions_list, session_key, config, &data) != EXIT_SUCCESS) {
+	if (netconf_generic(server, session_key, config, &data) != EXIT_SUCCESS) {
 		if (err_reply == NULL) {
 			reply = create_error("Killing of session failed.");
 		} else {
@@ -1286,12 +1292,12 @@
 	return reply;
 }
 
-json_object *handle_op_disconnect(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_disconnect(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	json_object *reply = NULL;
 	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: Disconnect session %s", session_key);
 
-	if (netconf_close(server, netconf_sessions_list, session_key) != EXIT_SUCCESS) {
+	if (netconf_close(server, session_key) != EXIT_SUCCESS) {
 		if (err_reply == NULL) {
 			reply = create_error("Invalid session identifier.");
 		} else {
@@ -1305,7 +1311,7 @@
 	return reply;
 }
 
-json_object *handle_op_kill(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_kill(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	json_object *reply = NULL;
 	const char *sid = NULL;
@@ -1318,7 +1324,7 @@
 		return create_error("Missing session-id parameter.");
 	}
 
-	if (netconf_killsession(server, netconf_sessions_list, session_key, sid) != EXIT_SUCCESS) {
+	if (netconf_killsession(server, session_key, sid) != EXIT_SUCCESS) {
 		if (err_reply == NULL) {
 			reply = create_error("Killing of session failed.");
 		} else {
@@ -1332,16 +1338,26 @@
 	return reply;
 }
 
-json_object *handle_op_reloadhello(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_reloadhello(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
+	struct nc_session *temp_session = NULL;
 	struct session_with_mutex * locked_session = NULL;
 	json_object *reply = NULL;
 	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: get info about session %s", session_key);
 
+	if (pthread_rwlock_rdlock(&session_lock) != 0) {
+		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		return NULL;
+	}
+
 	locked_session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
 	if ((locked_session != NULL) && (locked_session->hello_message != NULL)) {
+		pthread_mutex_lock(&locked_session->lock);
+		if (pthread_rwlock_unlock(&session_lock) != 0) {
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		}
 		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "creating temporal NC session.");
-		struct nc_session *temp_session = nc_session_connect_channel(locked_session->session, NULL);
+		temp_session = nc_session_connect_channel(locked_session->session, NULL);
 		if (temp_session != NULL) {
 			prepare_status_message(server, locked_session, temp_session);
 			ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "closing temporal NC session.");
@@ -1350,7 +1366,11 @@
 			ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Reload hello failed due to channel establishment");
 			reply = create_error("Reload was unsuccessful, connection failed.");
 		}
+		pthread_mutex_unlock(&locked_session->lock);
 	} else {
+		if (pthread_rwlock_unlock(&session_lock) != 0) {
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		}
 		reply = create_error("Invalid session identifier.");
 	}
 
@@ -1360,23 +1380,36 @@
 	return reply;
 }
 
-json_object *handle_op_info(server_rec *server, apr_pool_t *pool, json_object *request, apr_hash_t *netconf_sessions_list, const char *session_key)
+json_object *handle_op_info(server_rec *server, apr_pool_t *pool, json_object *request, const char *session_key)
 {
 	json_object *reply = NULL;
-	struct session_with_mutex * locked_session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
+	struct session_with_mutex * locked_session = NULL;
 	ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: get info about session %s", session_key);
 
+	if (pthread_rwlock_rdlock(&session_lock) != 0) {
+		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+	}
+
 	locked_session = (struct session_with_mutex *)apr_hash_get(netconf_sessions_list, session_key, APR_HASH_KEY_STRING);
 	if (locked_session != NULL) {
+		pthread_mutex_lock(&locked_session->lock);
+		if (pthread_rwlock_unlock(&session_lock) != 0) {
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		}
 		if (locked_session->hello_message != NULL) {
 			reply = locked_session->hello_message;
 		} else {
 			reply = create_error("Invalid session identifier.");
 		}
+		pthread_mutex_unlock(&locked_session->lock);
 	} else {
+		if (pthread_rwlock_unlock(&session_lock) != 0) {
+			ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while unlocking rwlock: %d (%s)", errno, strerror(errno));
+		}
 		reply = create_error("Invalid session identifier.");
 	}
 
+
 	return reply;
 }
 
@@ -1396,7 +1429,6 @@
 	NC_DATASTORE ds_type_s = -1;
 	char *chunked_out_msg = NULL;
 	apr_pool_t * pool = ((struct pass_to_thread*)arg)->pool;
-	apr_hash_t *netconf_sessions_list = ((struct pass_to_thread*)arg)->netconf_sessions_list;
 	server_rec * server = ((struct pass_to_thread*)arg)->server;
 	int client = ((struct pass_to_thread*)arg)->client;
 
@@ -1435,9 +1467,10 @@
 			break;
 		}
 
-
+		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Get framed message...");
 		buffer = get_framed_message(server, client);
 
+		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Check read buffer.");
 		if (buffer != NULL) {
 			enum json_tokener_error jerr;
 			request = json_tokener_parse_verbose(buffer, &jerr);
@@ -1469,22 +1502,22 @@
 			/* process required operation */
 			switch (operation) {
 			case MSG_CONNECT:
-				reply = handle_op_connect(server, pool, request, netconf_sessions_list);
+				reply = handle_op_connect(server, pool, request);
 				break;
 			case MSG_GET:
-				reply = handle_op_get(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_get(server, pool, request, session_key);
 				break;
 			case MSG_GETCONFIG:
-				reply = handle_op_getconfig(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_getconfig(server, pool, request, session_key);
 				break;
 			case MSG_GETSCHEMA:
-				reply = handle_op_getschema(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_getschema(server, pool, request, session_key);
 				break;
 			case MSG_EDITCONFIG:
-				reply = handle_op_editconfig(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_editconfig(server, pool, request, session_key);
 				break;
 			case MSG_COPYCONFIG:
-				reply = handle_op_copyconfig(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_copyconfig(server, pool, request, session_key);
 				break;
 
 			case MSG_DELETECONFIG:
@@ -1505,15 +1538,15 @@
 				switch(operation) {
 				case MSG_DELETECONFIG:
 					ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: delete-config (session %s)", session_key);
-					status = netconf_deleteconfig(server, netconf_sessions_list, session_key, ds_type_t);
+					status = netconf_deleteconfig(server, session_key, ds_type_t);
 					break;
 				case MSG_LOCK:
 					ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: lock (session %s)", session_key);
-					status = netconf_lock(server, netconf_sessions_list, session_key, ds_type_t);
+					status = netconf_lock(server, session_key, ds_type_t);
 					break;
 				case MSG_UNLOCK:
 					ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Request: unlock (session %s)", session_key);
-					status = netconf_unlock(server, netconf_sessions_list, session_key, ds_type_t);
+					status = netconf_unlock(server, session_key, ds_type_t);
 					break;
 				default:
 					status = -1;
@@ -1534,19 +1567,19 @@
 				}
 				break;
 			case MSG_KILL:
-				reply = handle_op_kill(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_kill(server, pool, request, session_key);
 				break;
 			case MSG_DISCONNECT:
-				reply = handle_op_disconnect(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_disconnect(server, pool, request, session_key);
 				break;
 			case MSG_RELOADHELLO:
-				reply = handle_op_reloadhello(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_reloadhello(server, pool, request, session_key);
 				break;
 			case MSG_INFO:
-				reply = handle_op_info(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_info(server, pool, request, session_key);
 				break;
 			case MSG_GENERIC:
-				reply = handle_op_generic(server, pool, request, netconf_sessions_list, session_key);
+				reply = handle_op_generic(server, pool, request, session_key);
 				break;
 			default:
 				ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "Unknown mod_netconf operation requested (%d)", operation);
@@ -1567,8 +1600,11 @@
 					}
 					break;
 				}
+				ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Send framed reply json object.");
 				send(client, chunked_out_msg, strlen(chunked_out_msg) + 1, 0);
+				ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Clean reply json object.");
 				json_object_put(reply);
+				ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Clean message buffer.");
 				free(chunked_out_msg);
 				chunked_out_msg = NULL;
 				if (buffer != NULL) {
@@ -1597,12 +1633,11 @@
  * \param[in] p  apr pool needed for hash table iterating
  * \param[in] ht  hash table of session_with_mutex structs
  */
-static void close_all_nc_sessions(server_rec* server, apr_pool_t *p, apr_hash_t *ht)
+static void close_all_nc_sessions(server_rec* server, apr_pool_t *p)
 {
 	apr_hash_index_t *hi;
 	void *val = NULL;
 	struct session_with_mutex *swm = NULL;
-	struct nc_session *ns = NULL;
 	const char *hashed_key = NULL;
 	apr_ssize_t hashed_key_length;
 	int ret;
@@ -1612,19 +1647,26 @@
 		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", ret, strerror(ret));
 		return;
 	}
-	for (hi = apr_hash_first(p, ht); hi; hi = apr_hash_next(hi)) {
+	for (hi = apr_hash_first(p, netconf_sessions_list); hi; hi = apr_hash_next(hi)) {
 		apr_hash_this(hi, (const void **) &hashed_key, &hashed_key_length, &val);
 		ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Closing NETCONF session (%s).", hashed_key);
 		swm = (struct session_with_mutex *) val;
 		if (swm != NULL) {
-			pthread_mutex_lock(&swm->lock);
-			if (swm->session != NULL) {
-				ns = swm->session;
-				nc_session_close(ns, NC_SESSION_TERM_CLOSED);
-				nc_session_free(ns);
-				swm->session = NULL;
-			}
+			//pthread_mutex_lock(&swm->lock);
+			//if (swm->session != NULL) {
+			//	swm->closed = 1;
+			//	ns = swm->session;
+			//	nc_session_close(ns, NC_SESSION_TERM_CLOSED);
+			//	nc_session_free(ns);
+			//	swm->session = NULL;
+			//}
+			//pthread_mutex_unlock(&swm->lock);
+
+			apr_hash_set(netconf_sessions_list, hashed_key, APR_HASH_KEY_STRING, NULL);
 			pthread_mutex_unlock(&swm->lock);
+
+			/* close_and_free_session handles locking on its own */
+			close_and_free_session(server, swm);
 		}
 	}
 	/* get exclusive access to sessions_list (conns) */
@@ -1633,8 +1675,10 @@
 	}
 }
 
-static void check_timeout_and_close(server_rec* server, apr_pool_t *p, apr_hash_t *ht)
+static void check_timeout_and_close(server_rec* server, apr_pool_t *p)
 {
+/** \todo fix locking */
+return;
 	apr_hash_index_t *hi;
 	void *val = NULL;
 	struct nc_session *ns = NULL;
@@ -1649,7 +1693,7 @@
 		ap_log_error (APLOG_MARK, APLOG_DEBUG, 0, server, "Error while locking rwlock: %d (%s)", ret, strerror(ret));
 		return;
 	}
-	for (hi = apr_hash_first(p, ht); hi; hi = apr_hash_next(hi)) {
+	for (hi = apr_hash_first(p, netconf_sessions_list); hi; hi = apr_hash_next(hi)) {
 		apr_hash_this(hi, (const void **) &hashed_key, &hashed_key_length, &val);
 		swm = (struct session_with_mutex *) val;
 		if (swm == NULL) {
@@ -1662,13 +1706,18 @@
 		pthread_mutex_lock(&swm->lock);
 		if ((current_time - swm->last_activity) > apr_time_from_sec(ACTIVITY_TIMEOUT)) {
 			ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, server, "Closing NETCONF session (%s).", hashed_key);
-			nc_session_close(ns, NC_SESSION_TERM_CLOSED);
-			nc_session_free (ns);
-			ns = NULL;
+			//nc_session_close(ns, NC_SESSION_TERM_CLOSED);
+			//nc_session_free (ns);
+			//ns = NULL;
 			/* remove session from the active sessions list */
-			apr_hash_set(ht, hashed_key, APR_HASH_KEY_STRING, NULL);
+			apr_hash_set(netconf_sessions_list, hashed_key, APR_HASH_KEY_STRING, NULL);
+			pthread_mutex_unlock(&swm->lock);
+
+			/* close_and_free_session handles locking on its own */
+			close_and_free_session(server, swm);
+		} else {
+			pthread_mutex_unlock(&swm->lock);
 		}
-		pthread_mutex_unlock(&swm->lock);
 	}
 	/* get exclusive access to sessions_list (conns) */
 	if (pthread_rwlock_unlock (&session_lock) != 0) {
@@ -1693,7 +1742,6 @@
 	unsigned int olds = 0, timediff = 0;
 	socklen_t len;
 	mod_netconf_cfg *cfg;
-	apr_hash_t *netconf_sessions_list;
 	struct pass_to_thread * arg;
 	pthread_t * ptids = calloc (1,sizeof(pthread_t));
 	struct timespec maxtime;
@@ -1747,7 +1795,7 @@
 	netconf_sessions_list = apr_hash_make(pool);
 
 	#ifdef WITH_NOTIFICATIONS
-	if (notification_init(pool, server, netconf_sessions_list) == -1) {
+	if (notification_init(pool, server) == -1) {
 		ap_log_error(APLOG_MARK, APLOG_ERR, 0, server, "libwebsockets initialization failed");
 		use_notifications = 0;
 	} else {
@@ -1793,7 +1841,7 @@
 		}
 		#endif
 		if (timediff > ACTIVITY_CHECK_INTERVAL) {
-			check_timeout_and_close(server, pool, netconf_sessions_list);
+			check_timeout_and_close(server, pool);
 		}
 
 		/* open incoming connection if any */
@@ -1860,7 +1908,7 @@
 	#endif
 
 	/* close all NETCONF sessions */
-	close_all_nc_sessions(server, pool, netconf_sessions_list);
+	close_all_nc_sessions(server, pool);
 
 	/* destroy rwlock */
 	pthread_rwlock_destroy(&session_lock);