Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision 7d7f5e3e22d4a07e37e90f73a61193fc2a664b39)
+++ uspace/lib/c/generic/loc.c	(revision 2a09dcb306884fcb1ded541284a93d92e6da3853)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2023 Jiri Svoboda
  * Copyright (c) 2007 Josef Cejka
+ * Copyright (c) 2011 Jiri Svoboda
  * All rights reserved.
  *
@@ -39,5 +39,8 @@
 #include <stdbool.h>
 
+static FIBRIL_MUTEX_INITIALIZE(loc_supp_block_mutex);
 static FIBRIL_MUTEX_INITIALIZE(loc_cons_block_mutex);
+
+static FIBRIL_MUTEX_INITIALIZE(loc_supplier_mutex);
 static FIBRIL_MUTEX_INITIALIZE(loc_consumer_mutex);
 
@@ -47,5 +50,8 @@
 static void *cat_change_arg = NULL;
 
+static async_sess_t *loc_supp_block_sess = NULL;
 static async_sess_t *loc_cons_block_sess = NULL;
+
+static async_sess_t *loc_supplier_sess = NULL;
 static async_sess_t *loc_consumer_sess = NULL;
 
@@ -102,5 +108,5 @@
 	if (!loc_callback_created) {
 		async_exch_t *exch =
-		    loc_exchange_begin_blocking();
+		    loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 
 		ipc_call_t answer;
@@ -129,49 +135,96 @@
 /** Start an async exchange on the loc session (blocking).
  *
+ * @param iface Location service interface to choose
+ *
  * @return New exchange.
  *
  */
-async_exch_t *loc_exchange_begin_blocking(void)
-{
-	fibril_mutex_lock(&loc_cons_block_mutex);
-
-	while (loc_cons_block_sess == NULL) {
-		clone_session(&loc_consumer_mutex, loc_consumer_sess,
-		    &loc_cons_block_sess);
-
-		if (loc_cons_block_sess == NULL)
-			loc_cons_block_sess =
-			    service_connect_blocking(SERVICE_LOC,
+async_exch_t *loc_exchange_begin_blocking(iface_t iface)
+{
+	switch (iface) {
+	case INTERFACE_LOC_SUPPLIER:
+		fibril_mutex_lock(&loc_supp_block_mutex);
+
+		while (loc_supp_block_sess == NULL) {
+			clone_session(&loc_supplier_mutex, loc_supplier_sess,
+			    &loc_supp_block_sess);
+
+			if (loc_supp_block_sess == NULL)
+				loc_supp_block_sess =
+				    service_connect_blocking(SERVICE_LOC,
+				    INTERFACE_LOC_SUPPLIER, 0, NULL);
+		}
+
+		fibril_mutex_unlock(&loc_supp_block_mutex);
+
+		clone_session(&loc_supplier_mutex, loc_supp_block_sess,
+		    &loc_supplier_sess);
+
+		return async_exchange_begin(loc_supp_block_sess);
+	case INTERFACE_LOC_CONSUMER:
+		fibril_mutex_lock(&loc_cons_block_mutex);
+
+		while (loc_cons_block_sess == NULL) {
+			clone_session(&loc_consumer_mutex, loc_consumer_sess,
+			    &loc_cons_block_sess);
+
+			if (loc_cons_block_sess == NULL)
+				loc_cons_block_sess =
+				    service_connect_blocking(SERVICE_LOC,
+				    INTERFACE_LOC_CONSUMER, 0, NULL);
+		}
+
+		fibril_mutex_unlock(&loc_cons_block_mutex);
+
+		clone_session(&loc_consumer_mutex, loc_cons_block_sess,
+		    &loc_consumer_sess);
+
+		return async_exchange_begin(loc_cons_block_sess);
+	default:
+		return NULL;
+	}
+}
+
+/** Start an async exchange on the loc session.
+ *
+ * @param iface Location service interface to choose
+ *
+ * @return New exchange.
+ *
+ */
+async_exch_t *loc_exchange_begin(iface_t iface)
+{
+	switch (iface) {
+	case INTERFACE_LOC_SUPPLIER:
+		fibril_mutex_lock(&loc_supplier_mutex);
+
+		if (loc_supplier_sess == NULL)
+			loc_supplier_sess =
+			    service_connect(SERVICE_LOC,
+			    INTERFACE_LOC_SUPPLIER, 0, NULL);
+
+		fibril_mutex_unlock(&loc_supplier_mutex);
+
+		if (loc_supplier_sess == NULL)
+			return NULL;
+
+		return async_exchange_begin(loc_supplier_sess);
+	case INTERFACE_LOC_CONSUMER:
+		fibril_mutex_lock(&loc_consumer_mutex);
+
+		if (loc_consumer_sess == NULL)
+			loc_consumer_sess =
+			    service_connect(SERVICE_LOC,
 			    INTERFACE_LOC_CONSUMER, 0, NULL);
-	}
-
-	fibril_mutex_unlock(&loc_cons_block_mutex);
-
-	clone_session(&loc_consumer_mutex, loc_cons_block_sess,
-	    &loc_consumer_sess);
-
-	return async_exchange_begin(loc_cons_block_sess);
-}
-
-/** Start an async exchange on the loc session.
- *
- * @return New exchange.
- *
- */
-async_exch_t *loc_exchange_begin(void)
-{
-	fibril_mutex_lock(&loc_consumer_mutex);
-
-	if (loc_consumer_sess == NULL)
-		loc_consumer_sess =
-		    service_connect(SERVICE_LOC,
-		    INTERFACE_LOC_CONSUMER, 0, NULL);
-
-	fibril_mutex_unlock(&loc_consumer_mutex);
-
-	if (loc_consumer_sess == NULL)
+
+		fibril_mutex_unlock(&loc_consumer_mutex);
+
+		if (loc_consumer_sess == NULL)
+			return NULL;
+
+		return async_exchange_begin(loc_consumer_sess);
+	default:
 		return NULL;
-
-	return async_exchange_begin(loc_consumer_sess);
+	}
 }
 
@@ -186,27 +239,8 @@
 }
 
-/** Register new server with loc.
- *
- * @param name Server name
- * @param rsrv Place to store new server object on success
- * @return EOK on succes or an error code
- */
-errno_t loc_server_register(const char *name, loc_srv_t **rsrv)
-{
-	async_exch_t *exch;
-	loc_srv_t *srv;
-
-	srv = calloc(1, sizeof(loc_srv_t));
-	if (srv == NULL)
-		return ENOMEM;
-
-	srv->sess = service_connect_blocking(SERVICE_LOC,
-	    INTERFACE_LOC_SUPPLIER, 0, NULL);
-	if (srv->sess == NULL) {
-		free(srv);
-		return ENOMEM;
-	}
-
-	exch = async_exchange_begin(srv->sess);
+/** Register new server with loc. */
+errno_t loc_server_register(const char *name)
+{
+	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_SUPPLIER);
 
 	ipc_call_t answer;
@@ -216,7 +250,5 @@
 	if (retval != EOK) {
 		async_forget(req);
-		async_exchange_end(exch);
-		async_hangup(srv->sess);
-		free(srv);
+		loc_exchange_end(exch);
 		return retval;
 	}
@@ -230,39 +262,19 @@
 	 */
 	async_wait_for(req, &retval);
-	async_exchange_end(exch);
-
-	if (retval != EOK) {
-		async_hangup(srv->sess);
-		free(srv);
-		return retval;
-	}
-
-	*rsrv = srv;
+	loc_exchange_end(exch);
+
 	return retval;
 }
 
-/** Unregister server from loc.
- *
- * Unregister server and free server object.
- *
- * @param srv Server object
- */
-void loc_server_unregister(loc_srv_t *srv)
-{
-	async_hangup(srv->sess);
-	free(srv);
-}
-
 /** Register new service.
  *
- * @param srv Server object
- * @param fqsn Fully qualified service name
- * @param sid  Service ID of new service
- *
- */
-errno_t loc_service_register(loc_srv_t *srv, const char *fqsn,
-    service_id_t *sid)
-{
-	async_exch_t *exch = async_exchange_begin(srv->sess);
+ * @param      fqsn  Fully qualified service name
+ * @param[out] sid   Service ID of new service
+ *
+ */
+errno_t loc_service_register(const char *fqsn, service_id_t *sid)
+{
+	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_SUPPLIER);
+
 	ipc_call_t answer;
 	aid_t req = async_send_0(exch, LOC_SERVICE_REGISTER, &answer);
@@ -271,5 +283,5 @@
 	if (retval != EOK) {
 		async_forget(req);
-		async_exchange_end(exch);
+		loc_exchange_end(exch);
 		return retval;
 	}
@@ -281,5 +293,5 @@
 	 */
 	async_wait_for(req, &retval);
-	async_exchange_end(exch);
+	loc_exchange_end(exch);
 
 	if (retval != EOK) {
@@ -298,15 +310,14 @@
 /** Unregister service.
  *
- * @param srv Server object
- * @param sid Service ID
- */
-errno_t loc_service_unregister(loc_srv_t *srv, service_id_t sid)
+ * @param sid	Service ID
+ */
+errno_t loc_service_unregister(service_id_t sid)
 {
 	async_exch_t *exch;
 	errno_t retval;
 
-	exch = async_exchange_begin(srv->sess);
+	exch = loc_exchange_begin_blocking(INTERFACE_LOC_SUPPLIER);
 	retval = async_req_1_0(exch, LOC_SERVICE_UNREGISTER, sid);
-	async_exchange_end(exch);
+	loc_exchange_end(exch);
 
 	return (errno_t)retval;
@@ -319,7 +330,7 @@
 
 	if (flags & IPC_FLAG_BLOCKING)
-		exch = loc_exchange_begin_blocking();
+		exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 	else {
-		exch = loc_exchange_begin();
+		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
 		if (exch == NULL)
 			return errno;
@@ -372,5 +383,5 @@
 
 	*name = NULL;
-	exch = loc_exchange_begin_blocking();
+	exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 
 	ipc_call_t answer;
@@ -452,7 +463,7 @@
 
 	if (flags & IPC_FLAG_BLOCKING)
-		exch = loc_exchange_begin_blocking();
+		exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 	else {
-		exch = loc_exchange_begin();
+		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
 		if (exch == NULL)
 			return errno;
@@ -501,7 +512,7 @@
 
 	if (flags & IPC_FLAG_BLOCKING)
-		exch = loc_exchange_begin_blocking();
+		exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 	else {
-		exch = loc_exchange_begin();
+		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
 		if (exch == NULL)
 			return errno;
@@ -537,5 +548,5 @@
 loc_object_type_t loc_id_probe(service_id_t handle)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking();
+	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 
 	sysarg_t type;
@@ -568,5 +579,5 @@
 int loc_null_create(void)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking();
+	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 
 	sysarg_t null_id;
@@ -583,5 +594,5 @@
 void loc_null_destroy(int null_id)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking();
+	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 	async_req_1_0(exch, LOC_NULL_DESTROY, (sysarg_t) null_id);
 	loc_exchange_end(exch);
@@ -600,19 +611,16 @@
 /** Add service to category.
  *
- * @param srv    Server object
- * @param svc_id Service ID
- * @param cat_id Category ID
- *
- * @return EOK on success or an error code
- */
-errno_t loc_service_add_to_cat(loc_srv_t *srv, service_id_t svc_id,
-    service_id_t cat_id)
+ * @param svc_id	Service ID
+ * @param cat_id	Category ID
+ * @return		EOK on success or an error code
+ */
+errno_t loc_service_add_to_cat(service_id_t svc_id, service_id_t cat_id)
 {
 	async_exch_t *exch;
 	errno_t retval;
 
-	exch = async_exchange_begin(srv->sess);
+	exch = loc_exchange_begin_blocking(INTERFACE_LOC_SUPPLIER);
 	retval = async_req_2_0(exch, LOC_SERVICE_ADD_TO_CAT, svc_id, cat_id);
-	async_exchange_end(exch);
+	loc_exchange_end(exch);
 
 	return retval;
@@ -633,5 +641,5 @@
 size_t loc_count_namespaces(void)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking();
+	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 	size_t size = loc_count_namespaces_internal(exch);
 	loc_exchange_end(exch);
@@ -642,5 +650,5 @@
 size_t loc_count_services(service_id_t ns_handle)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking();
+	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 	size_t size = loc_count_services_internal(exch, ns_handle);
 	loc_exchange_end(exch);
@@ -653,5 +661,5 @@
 	/* Loop until read is succesful */
 	while (true) {
-		async_exch_t *exch = loc_exchange_begin_blocking();
+		async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 		size_t count = loc_count_namespaces_internal(exch);
 		loc_exchange_end(exch);
@@ -664,5 +672,5 @@
 			return 0;
 
-		exch = loc_exchange_begin();
+		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
 
 		ipc_call_t answer;
@@ -702,5 +710,5 @@
 	/* Loop until read is succesful */
 	while (true) {
-		async_exch_t *exch = loc_exchange_begin_blocking();
+		async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 		size_t count = loc_count_services_internal(exch, ns_handle);
 		loc_exchange_end(exch);
@@ -713,5 +721,5 @@
 			return 0;
 
-		exch = loc_exchange_begin();
+		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
 
 		ipc_call_t answer;
@@ -750,5 +758,5 @@
     sysarg_t *id_buf, size_t buf_size, size_t *act_size)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking();
+	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
 
 	ipc_call_t answer;
