Index: uspace/lib/c/generic/clipboard.c
===================================================================
--- uspace/lib/c/generic/clipboard.c	(revision 007e6efa14f9116036c5ff0b040b3fbedee25b6f)
+++ uspace/lib/c/generic/clipboard.c	(revision b0f00a9ed1b00bda8a286a4c4bbe625a7f410bc6)
@@ -39,7 +39,8 @@
 
 #include <clipboard.h>
-#include <ipc/ns.h>
+#include <ns.h>
 #include <ipc/services.h>
 #include <ipc/clipboard.h>
+#include <fibril_synch.h>
 #include <async.h>
 #include <str.h>
@@ -47,13 +48,33 @@
 #include <malloc.h>
 
-static int clip_phone = -1;
-
-/** Connect to clipboard server
- *
- */
-static void clip_connect(void)
-{
-	while (clip_phone < 0)
-		clip_phone = service_connect_blocking(SERVICE_CLIPBOARD, 0, 0);
+static FIBRIL_MUTEX_INITIALIZE(clip_mutex);
+static async_sess_t *clip_sess = NULL;
+
+/** Start an async exchange on the clipboard session.
+ *
+ * @return New exchange.
+ *
+ */
+static async_exch_t *clip_exchange_begin(void)
+{
+	fibril_mutex_lock(&clip_mutex);
+	
+	while (clip_sess == NULL)
+		clip_sess = service_connect_blocking(EXCHANGE_SERIALIZE,
+		    SERVICE_CLIPBOARD, 0, 0);
+	
+	fibril_mutex_unlock(&clip_mutex);
+	
+	return async_exchange_begin(clip_sess);
+}
+
+/** Finish an async exchange on the clipboard session.
+ *
+ * @param exch Exchange to be finished.
+ *
+ */
+static void clip_exchange_end(async_exch_t *exch)
+{
+	async_exchange_end(exch);
 }
 
@@ -73,22 +94,20 @@
 	
 	if (size == 0) {
-		async_serialize_start();
-		clip_connect();
-		
-		sysarg_t rc = async_req_1_0(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_NONE);
-		
-		async_serialize_end();
+		async_exch_t *exch = clip_exchange_begin();
+		sysarg_t rc = async_req_1_0(exch, CLIPBOARD_PUT_DATA,
+		    CLIPBOARD_TAG_NONE);
+		clip_exchange_end(exch);
 		
 		return (int) rc;
 	} else {
-		async_serialize_start();
-		clip_connect();
-		
-		aid_t req = async_send_1(clip_phone, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA, NULL);
-		sysarg_t rc = async_data_write_start(clip_phone, (void *) str, size);
+		async_exch_t *exch = clip_exchange_begin();
+		aid_t req = async_send_1(exch, CLIPBOARD_PUT_DATA, CLIPBOARD_TAG_DATA,
+		    NULL);
+		sysarg_t rc = async_data_write_start(exch, (void *) str, size);
+		clip_exchange_end(exch);
+		
 		if (rc != EOK) {
 			sysarg_t rc_orig;
 			async_wait_for(req, &rc_orig);
-			async_serialize_end();
 			if (rc_orig == EOK)
 				return (int) rc;
@@ -98,5 +117,4 @@
 		
 		async_wait_for(req, &rc);
-		async_serialize_end();
 		
 		return (int) rc;
@@ -117,12 +135,11 @@
 	/* Loop until clipboard read succesful */
 	while (true) {
-		async_serialize_start();
-		clip_connect();
+		async_exch_t *exch = clip_exchange_begin();
 		
 		sysarg_t size;
 		sysarg_t tag;
-		sysarg_t rc = async_req_0_2(clip_phone, CLIPBOARD_CONTENT, &size, &tag);
-		
-		async_serialize_end();
+		sysarg_t rc = async_req_0_2(exch, CLIPBOARD_CONTENT, &size, &tag);
+		
+		clip_exchange_end(exch);
 		
 		if (rc != EOK)
@@ -145,8 +162,9 @@
 				return ENOMEM;
 			
-			async_serialize_start();
-			
-			aid_t req = async_send_1(clip_phone, CLIPBOARD_GET_DATA, tag, NULL);
-			rc = async_data_read_start(clip_phone, (void *) sbuf, size);
+			exch = clip_exchange_begin();
+			aid_t req = async_send_1(exch, CLIPBOARD_GET_DATA, tag, NULL);
+			rc = async_data_read_start(exch, (void *) sbuf, size);
+			clip_exchange_end(exch);
+			
 			if ((int) rc == EOVERFLOW) {
 				/*
@@ -154,5 +172,4 @@
 				 * the last call of CLIPBOARD_CONTENT
 				 */
-				async_serialize_end();
 				break;
 			}
@@ -161,5 +178,4 @@
 				sysarg_t rc_orig;
 				async_wait_for(req, &rc_orig);
-				async_serialize_end();
 				if (rc_orig == EOK)
 					return (int) rc;
@@ -169,5 +185,4 @@
 			
 			async_wait_for(req, &rc);
-			async_serialize_end();
 			
 			if (rc == EOK) {
