Index: trunk/kernel/kern/process.c
===================================================================
--- trunk/kernel/kern/process.c	(revision 438)
+++ trunk/kernel/kern/process.c	(revision 440)
@@ -106,4 +106,5 @@
     char        rx_path[40];
     char        tx_path[40];
+    xptr_t      file_xp;
     xptr_t      chdev_xp;
     chdev_t *   chdev_ptr;
@@ -179,4 +180,11 @@
         assert( (stdin_id == 0) , __FUNCTION__ , "stdin index must be 0" );
 
+#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
+cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_REFERENCE_INIT )
+printk("\n[DBG] %s : thread %x / stdin open for process %x / cycle %d\n", 
+__FUNCTION__ , CURRENT_THREAD , pid , cycle );
+#endif
+
         // create stdout pseudo file          
         error = vfs_open( process,
@@ -190,4 +198,11 @@
         assert( (stdout_id == 1) , __FUNCTION__ , "stdout index must be 1" );
 
+#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
+cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_REFERENCE_INIT )
+printk("\n[DBG] %s : thread %x / stdout open for process %x / cycle %d\n", 
+__FUNCTION__ , CURRENT_THREAD , pid , cycle );
+#endif
+
         // create stderr pseudo file          
         error = vfs_open( process,
@@ -201,9 +216,19 @@
         assert( (stderr_id == 2) , __FUNCTION__ , "stderr index must be 2" );
 
+#if (DEBUG_PROCESS_REFERENCE_INIT & 1)
+cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_REFERENCE_INIT )
+printk("\n[DBG] %s : thread %x / stderr open for process %x / cycle %d\n", 
+__FUNCTION__ , CURRENT_THREAD , pid , cycle );
+#endif
+
     }
     else                                            // normal user process 
     {
+        // get extended pointer on stdin pseudo file in model process
+        file_xp = (xptr_t)hal_remote_lwd( XPTR( model_cxy , &model_ptr->fd_array.array[0] ) );
+
         // get extended pointer on model process TXT chdev
-        chdev_xp = chdev_from_file( model_ptr->fd_array.array[0] );
+        chdev_xp = chdev_from_file( file_xp );
  
         // get cluster and local pointer on chdev
@@ -374,6 +399,6 @@
 uint32_t cycle = (uint32_t)hal_get_cycles();
 if( DEBUG_PROCESS_DESTROY )
-printk("\n[DBG] %s : thread %x enter to destroy process %x (pid = %x) / cycle %d\n",
-__FUNCTION__ , CURRENT_THREAD , process, pid , cycle );
+printk("\n[DBG] %s : thread %x enter in cluster %x / pid %x / process %x / cycle %d\n",
+__FUNCTION__ , CURRENT_THREAD , pid , process , cycle );
 #endif
 
@@ -401,6 +426,6 @@
     }
 
-    // release the process PID to cluster manager
-    cluster_pid_release( pid );
+    // release the process PID to cluster manager if owner cluster
+    if( CXY_FROM_PID( pid ) == local_cxy ) cluster_pid_release( pid );
 
     // FIXME close all open files and update dirty [AG]
@@ -507,4 +532,9 @@
     XLIST_FOREACH( root_xp , iter_xp )
     {
+        // atomically increment responses counter
+        hal_atomic_add( (void *)&rpc.responses , 1 );
+
+        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
+        process_cxy = GET_CXY( process_xp );
 
 #if DEBUG_PROCESS_SIGACTION 
@@ -513,10 +543,4 @@
 __FUNCTION__ , process_action_str( action_type ) , pid , process_cxy );
 #endif
-        // atomically increment responses counter
-        hal_atomic_add( (void *)&rpc.responses , 1 );
-
-        process_xp  = XLIST_ELEMENT( iter_xp , process_t , copies_list );
-        process_cxy = GET_CXY( process_xp );
-
         // call RPC in target cluster
         rpc_process_sigaction_client( process_cxy , &rpc );
@@ -529,5 +553,5 @@
     hal_restore_irq( save_sr);
 
-    // client deschedule : will be unblocked by the last RPC server thread 
+    // client thread deschedule : will be unblocked by the last RPC server thread 
     sched_yield("blocked on rpc_process_sigaction");
 
@@ -542,5 +566,6 @@
 
 /////////////////////////////////////////////////
-void process_block_threads( process_t * process )
+void process_block_threads( process_t * process,
+                            xptr_t      client_xp )
 {
     thread_t          * target;         // pointer on target thread 
@@ -567,5 +592,5 @@
     spinlock_lock( &process->th_lock );
 
-    // loop to block all threads but the main thread
+    // loop on target process local threads 
     // we use both "ltid" and "count" because it can exist "holes" in th_tbl
     for( ltid = 0 , count = 0 , ack_count = 0 ; count < process->th_nr ; ltid++ )
@@ -577,6 +602,7 @@
             count++;
 
-            // main thread should not be deleted
-            if( (ltid != 0) || (owner_cxy != local_cxy) )
+            // main thread and client thread should not be blocked
+            if( ((ltid != 0) || (owner_cxy != local_cxy)) &&         // not main thread
+                (client_xp) != XPTR( local_cxy , target ) )          // not client thread
             {
                 // set the global blocked bit in target thread descriptor.
@@ -626,14 +652,20 @@
 }  // end process_block_threads()
 
-///////////////////////////////////////////////////
-void process_unblock_threads( process_t * process )
-{
-    thread_t          * target;        // pointer on target thead 
+/////////////////////////////////////////////////
+void process_delete_threads( process_t * process,
+                             xptr_t      client_xp )
+{
     thread_t          * this;          // pointer on calling thread 
+    thread_t          * target;        // local pointer on target thread 
+    xptr_t              target_xp;     // extended pointer on target thread
+    cxy_t               owner_cxy;     // owner process cluster
     uint32_t            ltid;          // index in process th_tbl
-    uint32_t            count;         // requests counter
+    uint32_t            count;         // threads counter
 
     // get calling thread pointer
     this = CURRENT_THREAD;
+
+    // get target process owner cluster
+    owner_cxy = CXY_FROM_PID( process->pid );
 
 #if DEBUG_PROCESS_SIGACTION
@@ -647,16 +679,22 @@
     spinlock_lock( &process->th_lock );
 
-    // loop on process threads to unblock all threads
+    // loop on target process local threads                       
     // we use both "ltid" and "count" because it can exist "holes" in th_tbl
-    for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
+    for( ltid = 0 , count = 0  ; count < process->th_nr ; ltid++ )
     {
         target = process->th_tbl[ltid];
 
-        if( target != NULL )             // thread found
+        if( target != NULL )    // valid thread  
         {
             count++;
-
-            // reset the global blocked bit in target thread descriptor.
-            thread_unblock( XPTR( local_cxy , target ) , THREAD_BLOCKED_GLOBAL );
+            target_xp = XPTR( local_cxy , target );
+
+            // main thread and client thread should not be blocked
+            if( ((ltid != 0) || (owner_cxy != local_cxy)) &&         // not main thread
+                (client_xp) != target_xp )                           // not client thread
+            {
+                // mark target thread for delete and block it
+                thread_delete( target_xp , process->pid , false );   // not forced 
+            }
         }
     }
@@ -672,12 +710,16 @@
 #endif
 
-}  // end process_unblock_threads()
-
-//////////////////////////////////////////////////
-void process_delete_threads( process_t * process )
-{
-    thread_t          * target;        // pointer on target thread 
+}  // end process_delete_threads()
+
+///////////////////////////////////////////////////
+void process_unblock_threads( process_t * process )
+{
+    thread_t          * target;        // pointer on target thead 
+    thread_t          * this;          // pointer on calling thread 
     uint32_t            ltid;          // index in process th_tbl
-    uint32_t            count;         // threads counter
+    uint32_t            count;         // requests counter
+
+    // get calling thread pointer
+    this = CURRENT_THREAD;
 
 #if DEBUG_PROCESS_SIGACTION
@@ -685,5 +727,5 @@
 if( DEBUG_PROCESS_SIGACTION < cycle )
 printk("\n[DBG] %s : thread %x enter for process %x in cluster %x / cycle %d\n",
-__FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle );
+__FUNCTION__ , this , process->pid , local_cxy , cycle );
 #endif
 
@@ -691,17 +733,16 @@
     spinlock_lock( &process->th_lock );
 
-    // loop to set the REQ_DELETE flag on all threads but the main
+    // loop on process threads to unblock all threads
     // we use both "ltid" and "count" because it can exist "holes" in th_tbl
-    for( ltid = 0 , count = 0  ; count < process->th_nr ; ltid++ )
+    for( ltid = 0 , count = 0 ; count < process->th_nr ; ltid++ )
     {
         target = process->th_tbl[ltid];
 
-        if( target != NULL ) 
+        if( target != NULL )             // thread found
         {
             count++;
-            
-            thread_kill( XPTR( local_cxy , target ), 
-                         false,                       // is_exit
-                         true );                      // is_forced
+
+            // reset the global blocked bit in target thread descriptor.
+            thread_unblock( XPTR( local_cxy , target ) , THREAD_BLOCKED_GLOBAL );
         }
     }
@@ -714,8 +755,8 @@
 if( DEBUG_PROCESS_SIGACTION < cycle )
 printk("\n[DBG] %s : thread %x exit for process %x in cluster %x / cycle %d\n",
-__FUNCTION__ , CURRENT_THREAD , process->pid , local_cxy , cycle );
-#endif
-
-}  // end process_delete_threads()
+__FUNCTION__ , this , process->pid , local_cxy , cycle );
+#endif
+
+}  // end process_unblock_threads()
 
 ///////////////////////////////////////////////
@@ -749,5 +790,5 @@
 
     // allocate memory for a new local process descriptor
-    // and initialise it from reference cluster if required
+    // and initialise it from reference cluster if not found
     if( !found )
     {
@@ -765,4 +806,11 @@
         if( error ) return NULL;
     }
+
+#if DEBUG_PROCESS_GET_LOCAL_COPY
+uint32_t cycle = (uint32_t)hal_get_cycles();
+if( DEBUG_PROCESS_GET_LOCAL_COPY < cycle )
+printk("\n[DBG] %s : enter in cluster %x / pid %x / process %x / cycle %d\n",
+__FUNCTION__ , local_cxy , pid , process_ptr , cycle );
+#endif
 
     return process_ptr;
@@ -1032,7 +1080,4 @@
     // check parent process is the reference process
     ref_xp = hal_remote_lwd( XPTR( parent_process_cxy , &parent_process_ptr->ref_xp ) );
-
-printk("\n@@@ %s : parent_cxy = %x / parent_ptr = %x / ref_cxy = %x / ref_ptr = %x\n",
-__FUNCTION__, parent_process_cxy, parent_process_ptr, GET_CXY( ref_xp ), GET_PTR( ref_xp ) );
 
     assert( (parent_process_xp == ref_xp ) , __FUNCTION__ ,
