Index: uspace/lib/c/generic/loc.c
===================================================================
--- uspace/lib/c/generic/loc.c	(revision 4c6fd56b8079778d8d40e0d5ffc6a1e8e8ad2b5b)
+++ uspace/lib/c/generic/loc.c	(revision be0ec5095e0bc6fbb2c0524886c24ac20993fdbc)
@@ -39,8 +39,5 @@
 #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);
 
@@ -50,8 +47,5 @@
 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;
 
@@ -108,5 +102,5 @@
 	if (!loc_callback_created) {
 		async_exch_t *exch =
-		    loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+		    loc_exchange_begin_blocking();
 
 		ipc_call_t answer;
@@ -135,96 +129,49 @@
 /** 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(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:
+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,
+			    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)
 		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_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);
 }
 
@@ -240,7 +187,4 @@
 
 /** Register new server with loc.
- *
- * XXX Proper impementation - currently cannot actually call
- * this function more than once.
  *
  * @param name Server name
@@ -257,5 +201,12 @@
 		return ENOMEM;
 
-	exch = loc_exchange_begin_blocking(INTERFACE_LOC_SUPPLIER);
+	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);
 
 	ipc_call_t answer;
@@ -265,5 +216,6 @@
 	if (retval != EOK) {
 		async_forget(req);
-		loc_exchange_end(exch);
+		async_exchange_end(exch);
+		async_hangup(srv->sess);
 		free(srv);
 		return retval;
@@ -278,7 +230,8 @@
 	 */
 	async_wait_for(req, &retval);
-	loc_exchange_end(exch);
-
-	if (retval != EOK) {
+	async_exchange_end(exch);
+
+	if (retval != EOK) {
+		async_hangup(srv->sess);
 		free(srv);
 		return retval;
@@ -293,10 +246,9 @@
  * Unregister server and free server object.
  *
- * XXX Proper implementation
- *
  * @param srv Server object
  */
 void loc_server_unregister(loc_srv_t *srv)
 {
+	async_hangup(srv->sess);
 	free(srv);
 }
@@ -312,8 +264,5 @@
     service_id_t *sid)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_SUPPLIER);
-
-	(void)srv;
-
+	async_exch_t *exch = async_exchange_begin(srv->sess);
 	ipc_call_t answer;
 	aid_t req = async_send_0(exch, LOC_SERVICE_REGISTER, &answer);
@@ -322,5 +271,5 @@
 	if (retval != EOK) {
 		async_forget(req);
-		loc_exchange_end(exch);
+		async_exchange_end(exch);
 		return retval;
 	}
@@ -332,5 +281,5 @@
 	 */
 	async_wait_for(req, &retval);
-	loc_exchange_end(exch);
+	async_exchange_end(exch);
 
 	if (retval != EOK) {
@@ -357,9 +306,7 @@
 	errno_t retval;
 
-	(void)srv;
-
-	exch = loc_exchange_begin_blocking(INTERFACE_LOC_SUPPLIER);
+	exch = async_exchange_begin(srv->sess);
 	retval = async_req_1_0(exch, LOC_SERVICE_UNREGISTER, sid);
-	loc_exchange_end(exch);
+	async_exchange_end(exch);
 
 	return (errno_t)retval;
@@ -372,7 +319,7 @@
 
 	if (flags & IPC_FLAG_BLOCKING)
-		exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+		exch = loc_exchange_begin_blocking();
 	else {
-		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
+		exch = loc_exchange_begin();
 		if (exch == NULL)
 			return errno;
@@ -425,5 +372,5 @@
 
 	*name = NULL;
-	exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+	exch = loc_exchange_begin_blocking();
 
 	ipc_call_t answer;
@@ -505,7 +452,7 @@
 
 	if (flags & IPC_FLAG_BLOCKING)
-		exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+		exch = loc_exchange_begin_blocking();
 	else {
-		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
+		exch = loc_exchange_begin();
 		if (exch == NULL)
 			return errno;
@@ -554,7 +501,7 @@
 
 	if (flags & IPC_FLAG_BLOCKING)
-		exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+		exch = loc_exchange_begin_blocking();
 	else {
-		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
+		exch = loc_exchange_begin();
 		if (exch == NULL)
 			return errno;
@@ -590,5 +537,5 @@
 loc_object_type_t loc_id_probe(service_id_t handle)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+	async_exch_t *exch = loc_exchange_begin_blocking();
 
 	sysarg_t type;
@@ -621,5 +568,5 @@
 int loc_null_create(void)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+	async_exch_t *exch = loc_exchange_begin_blocking();
 
 	sysarg_t null_id;
@@ -636,5 +583,5 @@
 void loc_null_destroy(int null_id)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+	async_exch_t *exch = loc_exchange_begin_blocking();
 	async_req_1_0(exch, LOC_NULL_DESTROY, (sysarg_t) null_id);
 	loc_exchange_end(exch);
@@ -665,7 +612,7 @@
 	errno_t retval;
 
-	exch = loc_exchange_begin_blocking(INTERFACE_LOC_SUPPLIER);
+	exch = async_exchange_begin(srv->sess);
 	retval = async_req_2_0(exch, LOC_SERVICE_ADD_TO_CAT, svc_id, cat_id);
-	loc_exchange_end(exch);
+	async_exchange_end(exch);
 
 	return retval;
@@ -686,5 +633,5 @@
 size_t loc_count_namespaces(void)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+	async_exch_t *exch = loc_exchange_begin_blocking();
 	size_t size = loc_count_namespaces_internal(exch);
 	loc_exchange_end(exch);
@@ -695,5 +642,5 @@
 size_t loc_count_services(service_id_t ns_handle)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+	async_exch_t *exch = loc_exchange_begin_blocking();
 	size_t size = loc_count_services_internal(exch, ns_handle);
 	loc_exchange_end(exch);
@@ -706,5 +653,5 @@
 	/* Loop until read is succesful */
 	while (true) {
-		async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+		async_exch_t *exch = loc_exchange_begin_blocking();
 		size_t count = loc_count_namespaces_internal(exch);
 		loc_exchange_end(exch);
@@ -717,5 +664,5 @@
 			return 0;
 
-		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
+		exch = loc_exchange_begin();
 
 		ipc_call_t answer;
@@ -755,5 +702,5 @@
 	/* Loop until read is succesful */
 	while (true) {
-		async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+		async_exch_t *exch = loc_exchange_begin_blocking();
 		size_t count = loc_count_services_internal(exch, ns_handle);
 		loc_exchange_end(exch);
@@ -766,5 +713,5 @@
 			return 0;
 
-		exch = loc_exchange_begin(INTERFACE_LOC_CONSUMER);
+		exch = loc_exchange_begin();
 
 		ipc_call_t answer;
@@ -803,5 +750,5 @@
     sysarg_t *id_buf, size_t buf_size, size_t *act_size)
 {
-	async_exch_t *exch = loc_exchange_begin_blocking(INTERFACE_LOC_CONSUMER);
+	async_exch_t *exch = loc_exchange_begin_blocking();
 
 	ipc_call_t answer;
