Index: kernel/generic/include/proc/program.h
===================================================================
--- kernel/generic/include/proc/program.h	(revision aadf01ebd2c032bc8dd43a6e06ae5715e6c2710f)
+++ kernel/generic/include/proc/program.h	(revision 936835e135a18adfccf27258eb51edd1dd5fe962)
@@ -45,20 +45,19 @@
  * A program is an abstraction of a freshly created (not yet running)
  * userspace task containing a main thread along with its userspace stack.
+ *
  */
 typedef struct program {
-	struct task *task;		/**< Program task */
-	struct thread *main_thread;	/**< Program main thread */
+	struct task *task;           /**< Program task */
+	struct thread *main_thread;  /**< Program main thread */
 } program_t;
 
 extern void *program_loader;
 
-extern void program_create(as_t *as, uintptr_t entry_addr, char *name,
-    program_t *p);
-extern int program_create_from_image(void *image_addr, char *name,
-    program_t *p);
-extern int program_create_loader(program_t *p, char *name);
-extern void program_ready(program_t *p);
+extern int program_create(as_t *, uintptr_t, char *, program_t *);
+extern int program_create_from_image(void *, char *, program_t *);
+extern int program_create_loader(program_t *, char *);
+extern void program_ready(program_t *);
 
-extern unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len);
+extern unative_t sys_program_spawn_loader(char *, size_t);
 
 #endif
Index: kernel/generic/src/proc/program.c
===================================================================
--- kernel/generic/src/proc/program.c	(revision aadf01ebd2c032bc8dd43a6e06ae5715e6c2710f)
+++ kernel/generic/src/proc/program.c	(revision 936835e135a18adfccf27258eb51edd1dd5fe962)
@@ -34,5 +34,5 @@
 /**
  * @file
- * @brief	Running userspace programs.
+ * @brief Running userspace programs.
  */
 
@@ -66,14 +66,16 @@
 /** Create a program using an existing address space.
  *
- * @param as		Address space containing a binary program image.
- * @param entry_addr	Program entry-point address in program address space.
- * @param name		Name to set for the program's task.
- * @param p		Buffer for storing program information.
- */
-void program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *p)
-{
-	as_area_t *a;
+ * @param as         Address space containing a binary program image.
+ * @param entry_addr Program entry-point address in program address space.
+ * @param name       Name to set for the program's task.
+ * @param prg        Buffer for storing program information.
+ *
+ * @return EOK on success or negative error code.
+ *
+ */
+int program_create(as_t *as, uintptr_t entry_addr, char *name, program_t *prg)
+{
 	uspace_arg_t *kernel_uarg;
-
+	
 	kernel_uarg = (uspace_arg_t *) malloc(sizeof(uspace_arg_t), 0);
 	kernel_uarg->uspace_entry = (void *) entry_addr;
@@ -83,20 +85,27 @@
 	kernel_uarg->uspace_uarg = NULL;
 	
-	p->task = task_create(as, name);
-	ASSERT(p->task);
-
+	prg->task = task_create(as, name);
+	if (!prg->task)
+		return ELIMIT;
+	
 	/*
-	 * Create the data as_area.
+	 * Create the data address space area.
 	 */
-	a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
+	as_area_t *area = as_area_create(as,
+	    AS_AREA_READ | AS_AREA_WRITE | AS_AREA_CACHEABLE,
 	    LOADED_PROG_STACK_PAGES_NO * PAGE_SIZE, USTACK_ADDRESS,
 	    AS_AREA_ATTR_NONE, &anon_backend, NULL);
-
+	if (!area)
+		return ENOMEM;
+	
 	/*
 	 * Create the main thread.
 	 */
-	p->main_thread = thread_create(uinit, kernel_uarg, p->task,
+	prg->main_thread = thread_create(uinit, kernel_uarg, prg->task,
 	    THREAD_FLAG_USPACE, "uinit", false);
-	ASSERT(p->main_thread);
+	if (!prg->main_thread)
+		return ELIMIT;
+	
+	return EOK;
 }
 
@@ -107,73 +116,72 @@
  * executable image. The task is returned in *task.
  *
- * @param image_addr	Address of an executable program image.
- * @param name		Name to set for the program's task.
- * @param p		Buffer for storing program info. If image_addr
- *			points to a loader image, p->task will be set to
- *			NULL and EOK will be returned.
+ * @param image_addr Address of an executable program image.
+ * @param name       Name to set for the program's task.
+ * @param prg        Buffer for storing program info. If image_addr
+ *                   points to a loader image, p->task will be set to
+ *                   NULL and EOK will be returned.
  *
  * @return EOK on success or negative error code.
- */
-int program_create_from_image(void *image_addr, char *name, program_t *p)
-{
-	as_t *as;
-	unsigned int rc;
-
-	as = as_create(0);
-	ASSERT(as);
-
-	rc = elf_load((elf_header_t *) image_addr, as, 0);
+ *
+ */
+int program_create_from_image(void *image_addr, char *name, program_t *prg)
+{
+	as_t *as = as_create(0);
+	if (!as)
+		return ENOMEM;
+	
+	unsigned int rc = elf_load((elf_header_t *) image_addr, as, 0);
 	if (rc != EE_OK) {
 		as_destroy(as);
-		p->task = NULL;
-		p->main_thread = NULL;
+		prg->task = NULL;
+		prg->main_thread = NULL;
+		
 		if (rc != EE_LOADER)
 			return ENOTSUP;
 		
 		/* Register image as the program loader */
-		ASSERT(program_loader == NULL);
+		if (program_loader != NULL)
+			return ELIMIT;
+		
 		program_loader = image_addr;
 		LOG("Registered program loader at 0x%" PRIp "\n",
 		    image_addr);
+		
 		return EOK;
 	}
-
-	program_create(as, ((elf_header_t *) image_addr)->e_entry, name, p);
-
-	return EOK;
+	
+	return program_create(as, ((elf_header_t *) image_addr)->e_entry,
+	    name, prg);
 }
 
 /** Create a task from the program loader image.
  *
- * @param p	Buffer for storing program info.
- * @param name	Name to set for the program's task.
+ * @param prg  Buffer for storing program info.
+ * @param name Name to set for the program's task.
  *
  * @return EOK on success or negative error code.
- */
-int program_create_loader(program_t *p, char *name)
-{
-	as_t *as;
-	unsigned int rc;
-	void *loader;
-
-	as = as_create(0);
-	ASSERT(as);
-
-	loader = program_loader;
+ *
+ */
+int program_create_loader(program_t *prg, char *name)
+{
+	as_t *as = as_create(0);
+	if (!as)
+		return ENOMEM;
+	
+	void *loader = program_loader;
 	if (!loader) {
 		printf("Cannot spawn loader as none was registered\n");
 		return ENOENT;
 	}
-
-	rc = elf_load((elf_header_t *) program_loader, as, ELD_F_LOADER);
+	
+	unsigned int rc = elf_load((elf_header_t *) program_loader, as,
+	    ELD_F_LOADER);
 	if (rc != EE_OK) {
 		as_destroy(as);
 		return ENOENT;
 	}
-
-	program_create(as, ((elf_header_t *) program_loader)->e_entry,
-	    name, p);
-
-	return EOK;
+	
+	return program_create(as, ((elf_header_t *) program_loader)->e_entry,
+	    name, prg);
 }
 
@@ -182,9 +190,10 @@
  * Switch program's main thread to the ready state.
  *
- * @param p Program to make ready.
- */
-void program_ready(program_t *p)
-{
-	thread_ready(p->main_thread);
+ * @param prg Program to make ready.
+ *
+ */
+void program_ready(program_t *prg)
+{
+	thread_ready(prg->main_thread);
 }
 
@@ -194,37 +203,34 @@
  * the task name.
  *
- * @param name			Name to set on the new task (typically the same
- *				as the command used to execute it).
- *
- * @return 0 on success or an error code from @ref errno.h.
+ * @param uspace_name Name to set on the new task (typically the same
+ *                    as the command used to execute it).
+ * @param name_len    Length of the name.
+ *
+ * @return EOK on success or an error code from @ref errno.h.
+ *
  */
 unative_t sys_program_spawn_loader(char *uspace_name, size_t name_len)
 {
-	program_t p;
-	int rc;
-	char namebuf[TASK_NAME_BUFLEN];
-
 	/* Cap length of name and copy it from userspace. */
-
 	if (name_len > TASK_NAME_BUFLEN - 1)
 		name_len = TASK_NAME_BUFLEN - 1;
-
-	rc = copy_from_uspace(namebuf, uspace_name, name_len);
+	
+	char namebuf[TASK_NAME_BUFLEN];
+	int rc = copy_from_uspace(namebuf, uspace_name, name_len);
 	if (rc != 0)
 		return (unative_t) rc;
-
+	
 	namebuf[name_len] = 0;
-
+	
 	/* Spawn the new task. */
-
-	rc = program_create_loader(&p, namebuf);
+	program_t prg;
+	rc = program_create_loader(&prg, namebuf);
 	if (rc != 0)
 		return rc;
-
+	
 	// FIXME: control the capabilities
-	cap_set(p.task, cap_get(TASK));
-
-	program_ready(&p);
-
+	cap_set(prg.task, cap_get(TASK));
+	program_ready(&prg);
+	
 	return EOK;
 }
Index: uspace/srv/net/socket/socket_client.c
===================================================================
--- uspace/srv/net/socket/socket_client.c	(revision aadf01ebd2c032bc8dd43a6e06ae5715e6c2710f)
+++ uspace/srv/net/socket/socket_client.c	(revision 936835e135a18adfccf27258eb51edd1dd5fe962)
@@ -580,5 +580,8 @@
 		fibril_rwlock_write_unlock(&socket_globals.lock);
 		fibril_condvar_wait(&socket->accept_signal, &socket->accept_lock);
+		// drop the accept lock to avoid deadlock
+		fibril_mutex_unlock(&socket->accept_lock);
 		fibril_rwlock_write_lock(&socket_globals.lock);
+		fibril_mutex_lock(&socket->accept_lock);
 	}
 	-- socket->blocked;
@@ -801,5 +804,8 @@
 		fibril_rwlock_read_unlock(&socket_globals.lock);
 		fibril_condvar_wait(&socket->receive_signal, &socket->receive_lock);
+		// drop the receive lock to avoid deadlock
+		fibril_mutex_unlock(&socket->receive_lock);
 		fibril_rwlock_read_lock(&socket_globals.lock);
+		fibril_mutex_lock(&socket->receive_lock);
 	}
 	-- socket->blocked;
Index: uspace/srv/net/tl/icmp/icmp.c
===================================================================
--- uspace/srv/net/tl/icmp/icmp.c	(revision aadf01ebd2c032bc8dd43a6e06ae5715e6c2710f)
+++ uspace/srv/net/tl/icmp/icmp.c	(revision 936835e135a18adfccf27258eb51edd1dd5fe962)
@@ -175,5 +175,5 @@
 /** Requests an echo message.
  *  Sends a packet with specified parameters to the target host and waits for the reply upto the given timeout.
- *  Blocks the caller until the reply or the timeout occurres.
+ *  Blocks the caller until the reply or the timeout occurs.
  *  @param[in] id The message identifier.
  *  @param[in] sequence The message sequence parameter.
@@ -221,6 +221,6 @@
 
 /** Tries to set the pending reply result as the received message type.
- *  If the reply data are still present, the reply timeouted and the parent fibril is awaken.
- *  The global lock is not released in this case to be reused by the parent fibril.
+ *  If the reply data is not present, the reply timed out and the other fibril
+ *  is already awake.
  *  Releases the packet.
  *  @param[in] packet The received reply message.
@@ -334,5 +334,5 @@
 	}
 
-	// unlock the globals and wait for a reply
+	// unlock the globals so that we can wait for the reply
 	fibril_rwlock_write_unlock(&icmp_globals.lock);
 
@@ -340,18 +340,16 @@
 	icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment);
 
-	// wait for a reply
+	// wait for the reply
 	// timeout in microseconds
 	if(ERROR_OCCURRED(fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, timeout * 1000))){
 		result = ERROR_CODE;
-
-		// lock the globals again and clean up
-		fibril_rwlock_write_lock(&icmp_globals.lock);
 	}else{
 		// read the result
 		result = reply->result;
-
-		// release the reply structure
-		fibril_mutex_unlock(&reply->mutex);
-	}
+	}
+
+	// drop the reply mutex before locking the globals again
+	fibril_mutex_unlock(&reply->mutex);
+	fibril_rwlock_write_lock(&icmp_globals.lock);
 
 	// destroy the reply structure
@@ -636,10 +634,8 @@
 		// set the result
 		reply->result = type;
-		// notify the main fibril
+		// notify the waiting fibril
 		fibril_condvar_signal(&reply->condvar);
-	}else{
-		// unlock only if no reply
-		fibril_rwlock_write_unlock(&icmp_globals.lock);
-	}
+	}
+	fibril_rwlock_write_unlock(&icmp_globals.lock);
 	return EOK;
 }
Index: uspace/srv/net/tl/udp/udp.c
===================================================================
--- uspace/srv/net/tl/udp/udp.c	(revision aadf01ebd2c032bc8dd43a6e06ae5715e6c2710f)
+++ uspace/srv/net/tl/udp/udp.c	(revision 936835e135a18adfccf27258eb51edd1dd5fe962)
@@ -418,5 +418,4 @@
 	struct sockaddr * addr;
 	size_t addrlen;
-	fibril_rwlock_t lock;
 	ipc_call_t answer;
 	int answer_count;
@@ -433,5 +432,4 @@
 
 	socket_cores_initialize(&local_sockets);
-	fibril_rwlock_initialize(&lock);
 
 	while(keep_on_going){
@@ -453,8 +451,6 @@
 				break;
 			case NET_SOCKET:
-				fibril_rwlock_write_lock(&lock);
 				*SOCKET_SET_SOCKET_ID(answer) = SOCKET_GET_SOCKET_ID(call);
 				res = socket_create(&local_sockets, app_phone, NULL, SOCKET_SET_SOCKET_ID(answer));
-				fibril_rwlock_write_unlock(&lock);
 				if(res == EOK){
 					if(tl_get_ip_packet_dimension(udp_globals.ip_phone, &udp_globals.dimensions, DEVICE_INVALID_ID, &packet_dimension) == EOK){
@@ -469,9 +465,7 @@
 				res = data_receive((void **) &addr, &addrlen);
 				if(res == EOK){
-					fibril_rwlock_read_lock(&lock);
 					fibril_rwlock_write_lock(&udp_globals.lock);
 					res = socket_bind(&local_sockets, &udp_globals.sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, udp_globals.last_used_port);
 					fibril_rwlock_write_unlock(&udp_globals.lock);
-					fibril_rwlock_read_unlock(&lock);
 					free(addr);
 				}
@@ -480,5 +474,4 @@
 				res = data_receive((void **) &addr, &addrlen);
 				if(res == EOK){
-					fibril_rwlock_read_lock(&lock);
 					fibril_rwlock_write_lock(&udp_globals.lock);
 					res = udp_sendto_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), addr, addrlen, SOCKET_GET_DATA_FRAGMENTS(call), SOCKET_SET_DATA_FRAGMENT_SIZE(answer), SOCKET_GET_FLAGS(call));
@@ -488,14 +481,11 @@
 						answer_count = 2;
 					}
-					fibril_rwlock_read_unlock(&lock);
 					free(addr);
 				}
 				break;
 			case NET_SOCKET_RECVFROM:
-				fibril_rwlock_read_lock(&lock);
 				fibril_rwlock_write_lock(&udp_globals.lock);
 				res = udp_recvfrom_message(&local_sockets, SOCKET_GET_SOCKET_ID(call), SOCKET_GET_FLAGS(call), &addrlen);
 				fibril_rwlock_write_unlock(&udp_globals.lock);
-				fibril_rwlock_read_unlock(&lock);
 				if(res > 0){
 					*SOCKET_SET_READ_DATA_LENGTH(answer) = res;
@@ -506,9 +496,7 @@
 				break;
 			case NET_SOCKET_CLOSE:
-				fibril_rwlock_write_lock(&lock);
 				fibril_rwlock_write_lock(&udp_globals.lock);
 				res = socket_destroy(udp_globals.net_phone, SOCKET_GET_SOCKET_ID(call), &local_sockets, &udp_globals.sockets, NULL);
 				fibril_rwlock_write_unlock(&udp_globals.lock);
-				fibril_rwlock_write_unlock(&lock);
 				break;
 			case NET_SOCKET_GETSOCKOPT:
