Index: generic/include/mm/as.h
===================================================================
--- generic/include/mm/as.h	(revision 6fa476f7e7159d484a144866a0e63ebf61cb85be)
+++ generic/include/mm/as.h	(revision eaa202a8d9109b184f9d772edcba8c0981997798)
@@ -60,4 +60,8 @@
 #define AS_AREA_DEVICE	8
 
+/** Address space area attributes. */
+#define AS_AREA_ATTR_NONE	0
+#define AS_AREA_ATTR_PARTIAL	1	/* Not fully initialized area. */
+
 /** Address space area structure.
  *
@@ -67,5 +71,6 @@
 struct as_area {
 	SPINLOCK_DECLARE(lock);
-	int flags;
+	int flags;		/**< Flags related to the memory represented by the address space area. */
+	int attributes;		/**< Attributes related to the address space area itself. */
 	count_t pages;		/**< Size of this area in multiples of PAGE_SIZE. */
 	__address base;		/**< Base address of this area. */
@@ -113,7 +118,7 @@
 extern void as_init(void);
 extern as_t *as_create(int flags);
-extern as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base);
+extern as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base, int attrs);
 extern __address as_area_resize(as_t *as, __address address, size_t size, int flags);
-int as_area_send(task_id_t id, __address base);
+int as_area_send(task_id_t dst_id, __address base);
 extern void as_set_mapping(as_t *as, __address page, __address frame);
 extern int as_page_fault(__address page);
Index: generic/src/ddi/ddi.c
===================================================================
--- generic/src/ddi/ddi.c	(revision 6fa476f7e7159d484a144866a0e63ebf61cb85be)
+++ generic/src/ddi/ddi.c	(revision eaa202a8d9109b184f9d772edcba8c0981997798)
@@ -93,5 +93,5 @@
 	if (writable)
 		flags |= AS_AREA_WRITE;
-	if (!as_area_create(t->as, flags, pages * PAGE_SIZE, vp)) {
+	if (!as_area_create(t->as, flags, pages * PAGE_SIZE, vp, AS_AREA_ATTR_NONE)) {
 		/*
 		 * The address space area could not have been created.
Index: generic/src/lib/elf.c
===================================================================
--- generic/src/lib/elf.c	(revision 6fa476f7e7159d484a144866a0e63ebf61cb85be)
+++ generic/src/lib/elf.c	(revision eaa202a8d9109b184f9d772edcba8c0981997798)
@@ -187,5 +187,5 @@
 		segment = ((void *) elf) + entry->p_offset;
 
-	a = as_area_create(as, flags, entry->p_memsz, entry->p_vaddr);
+	a = as_area_create(as, flags, entry->p_memsz, entry->p_vaddr, AS_AREA_ATTR_NONE);
 	if (!a)
 		return EE_MEMORY;
Index: generic/src/mm/as.c
===================================================================
--- generic/src/mm/as.c	(revision 6fa476f7e7159d484a144866a0e63ebf61cb85be)
+++ generic/src/mm/as.c	(revision eaa202a8d9109b184f9d772edcba8c0981997798)
@@ -127,11 +127,12 @@
  *
  * @param as Target address space.
- * @param flags Flags of the area.
+ * @param flags Flags of the area memory.
  * @param size Size of area.
  * @param base Base address of area.
+ * @param attrs Attributes of the area.
  *
  * @return Address space area on success or NULL on failure.
  */
-as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base)
+as_area_t *as_area_create(as_t *as, int flags, size_t size, __address base, int attrs)
 {
 	ipl_t ipl;
@@ -162,4 +163,5 @@
 	
 	a->flags = flags;
+	a->attributes = attrs;
 	a->pages = SIZE2FRAMES(size);
 	a->base = base;
@@ -290,6 +292,6 @@
  * space area and any associated mapping is preserved.
  *
- * @param id Task ID of the accepting task.
- * @param base Base address of the source address space area.
+ * @param dst_id Task ID of the accepting task.
+ * @param src_base Base address of the source address space area.
  *
  * @return 0 on success or ENOENT if there is no such task or
@@ -299,19 +301,19 @@
  *	   address space area.
  */
-int as_area_send(task_id_t id, __address base)
+int as_area_send(task_id_t dst_id, __address src_base)
 {
 	ipl_t ipl;
 	task_t *t;
 	count_t i;
-	as_t *as;
+	as_t *dst_as;
 	__address dst_base;
-	int flags;
-	size_t size;
-	as_area_t *area;
+	int src_flags;
+	size_t src_size;
+	as_area_t *src_area, *dst_area;
 	
 	ipl = interrupts_disable();
 	spinlock_lock(&tasks_lock);
 	
-	t = task_find_by_id(id);
+	t = task_find_by_id(dst_id);
 	if (!NULL) {
 		spinlock_unlock(&tasks_lock);
@@ -323,8 +325,8 @@
 	spinlock_unlock(&tasks_lock);
 
-	as = t->as;
+	dst_as = t->as;
 	dst_base = (__address) t->accept_arg.base;
 	
-	if (as == AS) {
+	if (dst_as == AS) {
 		/*
 		 * The two tasks share the entire address space.
@@ -337,6 +339,6 @@
 	
 	spinlock_lock(&AS->lock);
-	area = find_area_and_lock(AS, base);
-	if (!area) {
+	src_area = find_area_and_lock(AS, src_base);
+	if (!src_area) {
 		/*
 		 * Could not find the source address space area.
@@ -347,11 +349,11 @@
 		return ENOENT;
 	}
-	size = area->pages * PAGE_SIZE;
-	flags = area->flags;
-	spinlock_unlock(&area->lock);
+	src_size = src_area->pages * PAGE_SIZE;
+	src_flags = src_area->flags;
+	spinlock_unlock(&src_area->lock);
 	spinlock_unlock(&AS->lock);
 
-	if ((t->accept_arg.task_id != TASK->taskid) || (t->accept_arg.size != size) ||
-	    (t->accept_arg.flags != flags)) {
+	if ((t->accept_arg.task_id != TASK->taskid) || (t->accept_arg.size != src_size) ||
+	    (t->accept_arg.flags != src_flags)) {
 		/*
 		 * Discrepancy in either task ID, size or flags.
@@ -363,7 +365,11 @@
 	
 	/*
-	 * Create copy of the address space area.
-	 */
-	if (!as_area_create(as, flags, size, dst_base)) {
+	 * Create copy of the source address space area.
+	 * The destination area is created with AS_AREA_ATTR_PARTIAL
+	 * attribute set which prevents race condition with
+	 * preliminary as_page_fault() calls.
+	 */
+	dst_area = as_area_create(dst_as, src_flags, src_size, dst_base, AS_AREA_ATTR_PARTIAL);
+	if (!dst_area) {
 		/*
 		 * Destination address space area could not be created.
@@ -374,16 +380,4 @@
 	}
 	
-	/*
-	 * NOTE: we have just introduced a race condition.
-	 * The destination task can try to attempt the newly
-	 * created area before its mapping is copied from
-	 * the source address space area. In result, frames
-	 * can get lost.
-	 *
-	 * Currently, this race is not solved, but one of the
-	 * possible solutions would be to sleep in as_page_fault()
-	 * when this situation is detected.
-	 */
-
 	memsetb((__address) &t->accept_arg, sizeof(as_area_acptsnd_arg_t), 0);
 	spinlock_unlock(&t->lock);
@@ -392,22 +386,22 @@
 	 * Avoid deadlock by first locking the address space with lower address.
 	 */
-	if (as < AS) {
-		spinlock_lock(&as->lock);
+	if (dst_as < AS) {
+		spinlock_lock(&dst_as->lock);
 		spinlock_lock(&AS->lock);
 	} else {
 		spinlock_lock(&AS->lock);
-		spinlock_lock(&as->lock);
-	}
-	
-	for (i = 0; i < SIZE2FRAMES(size); i++) {
+		spinlock_lock(&dst_as->lock);
+	}
+	
+	for (i = 0; i < SIZE2FRAMES(src_size); i++) {
 		pte_t *pte;
 		__address frame;
 			
 		page_table_lock(AS, false);
-		pte = page_mapping_find(AS, base + i*PAGE_SIZE);
+		pte = page_mapping_find(AS, src_base + i*PAGE_SIZE);
 		if (pte && PTE_VALID(pte)) {
 			ASSERT(PTE_PRESENT(pte));
 			frame = PTE_GET_FRAME(pte);
-			if (!(flags & AS_AREA_DEVICE))
+			if (!(src_flags & AS_AREA_DEVICE))
 				frame_reference_add(ADDR2PFN(frame));
 			page_table_unlock(AS, false);
@@ -417,11 +411,20 @@
 		}
 		
-		page_table_lock(as, false);
-		page_mapping_insert(as, dst_base + i*PAGE_SIZE, frame, area_flags_to_page_flags(flags));
-		page_table_unlock(as, false);
-	}
+		page_table_lock(dst_as, false);
+		page_mapping_insert(dst_as, dst_base + i*PAGE_SIZE, frame, area_flags_to_page_flags(src_flags));
+		page_table_unlock(dst_as, false);
+	}
+
+	/*
+	 * Now the destination address space area has been
+	 * fully initialized. Clear the AS_AREA_ATTR_PARTIAL
+	 * attribute.
+	 */	
+	spinlock_lock(&dst_area->lock);
+	dst_area->attributes &= ~AS_AREA_ATTR_PARTIAL;
+	spinlock_unlock(&dst_area->lock);
 	
 	spinlock_unlock(&AS->lock);
-	spinlock_unlock(&as->lock);
+	spinlock_unlock(&dst_as->lock);
 	interrupts_restore(ipl);
 	
@@ -485,4 +488,14 @@
 		spinlock_unlock(&AS->lock);
 		return 0;
+	}
+
+	if (area->attributes & AS_AREA_ATTR_PARTIAL) {
+		/*
+		 * The address space area is not fully initialized.
+		 * Avoid possible race by returning error.
+		 */
+		spinlock_unlock(&area->lock);
+		spinlock_unlock(&AS->lock);
+		return 0;		
 	}
 
@@ -840,5 +853,5 @@
 __native sys_as_area_create(__address address, size_t size, int flags)
 {
-	if (as_area_create(AS, flags, size, address))
+	if (as_area_create(AS, flags, size, address, AS_AREA_ATTR_NONE))
 		return (__native) address;
 	else
Index: generic/src/proc/task.c
===================================================================
--- generic/src/proc/task.c	(revision 6fa476f7e7159d484a144866a0e63ebf61cb85be)
+++ generic/src/proc/task.c	(revision eaa202a8d9109b184f9d772edcba8c0981997798)
@@ -152,5 +152,6 @@
 	 * Create the data as_area.
 	 */
-	a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE, LOADED_PROG_STACK_PAGES_NO*PAGE_SIZE, USTACK_ADDRESS);
+	a = as_area_create(as, AS_AREA_READ | AS_AREA_WRITE, LOADED_PROG_STACK_PAGES_NO*PAGE_SIZE,
+		USTACK_ADDRESS, AS_AREA_ATTR_NONE);
 
 	t = thread_create(uinit, kernel_uarg, task, 0, "uinit");
