From: Samuel Lepetit Date: Mon, 14 May 2012 14:37:07 +0000 (+0200) Subject: Change the way the Process are killed, since we need the java stack to be empty ... X-Git-Tag: v3_9_90~569^2~19^2~83 X-Git-Url: http://info.iut-bm.univ-fcomte.fr/pub/gitweb/simgrid.git/commitdiff_plain/e3b238eaf75f5bbe14b203615c1bdc4f4b5247ed Change the way the Process are killed, since we need the java stack to be empty (IE, the "run" call must have returned). Updated the examples tesh to match it. Updated the changelog --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 76e99d88a4..1f3d7a0778 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,7 +102,7 @@ set(JMSG_JAVA_SRC org/simgrid/msg/MsgException.java org/simgrid/msg/NativeException.java org/simgrid/msg/Process.java - org/simgrid/msg/ProcessKilled.java + org/simgrid/msg/ProcessKilledException.java org/simgrid/msg/ProcessNotFoundException.java org/simgrid/msg/Task.java org/simgrid/msg/TaskCancelledException.java diff --git a/ChangeLog b/ChangeLog index 2845ecd22d..67536934cb 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,7 @@ SimGrid-java (3.6.1) unstable; urgency=low * Add "sleep" in Process with Thread-like syntax/use. * Change the way the Process are created in ApplicationHandler: a full constructor is now needed for your child classes. + * Change the way Process are created: Process are no longer a Thread subclass. -- $date Da SimGrid team SimGrid-java (3.6) unstable; urgency=low diff --git a/examples/master_slave_kill/Master.java b/examples/master_slave_kill/Master.java index 38c6ffbd66..98c1d0451c 100644 --- a/examples/master_slave_kill/Master.java +++ b/examples/master_slave_kill/Master.java @@ -41,7 +41,6 @@ public class Master extends Process { break; } } - process2.kill(); Msg.info("Process2 is now killed, should exit now"); diff --git a/examples/master_slave_kill/Slave.java b/examples/master_slave_kill/Slave.java index 8f2140a3c4..1bc7229bea 100644 --- a/examples/master_slave_kill/Slave.java +++ b/examples/master_slave_kill/Slave.java @@ -26,7 +26,6 @@ public class Slave extends Process { Msg.info("Send Mail1!"); task.send("mail1"); - Msg.info("Send Mail2 !"); Task task2 = Task.receive("mail2"); Msg.info("Receive Mail2!"); } diff --git a/examples/master_slave_kill/kill.tesh b/examples/master_slave_kill/kill.tesh index ec4c84dc26..6ae6f7380f 100644 --- a/examples/master_slave_kill/kill.tesh +++ b/examples/master_slave_kill/kill.tesh @@ -3,17 +3,14 @@ ! output sort $ java -cp .:${srcdir:=.}/examples:${srcdir:=.}/simgrid.jar master_slave_kill/MsKill ${srcdir:=.}/examples/master_slave_kill/platform.xml -> Thread-1: I ignore that other exception > [0.000000] [jmsg/INFO] Ready to run MSG_MAIN > [0.013010] [jmsg/INFO] Done running MSG_MAIN > [0.013010] [jmsg/INFO] MSG_main finished > [0.013010] [jmsg/INFO] Clean java world > [0.013010] [jmsg/INFO] Clean native world -> [0.013010] [jmsg/INFO] Process slave has been killed. > [alice:slave:(2) 0.000000] [jmsg/INFO] Slave Hello! > [alice:slave:(2) 0.000000] [jmsg/INFO] Send Mail1! > [bob:master:(1) 0.000000] [jmsg/INFO] Master Hello! > [bob:master:(1) 0.000000] [jmsg/INFO] Create process on host 'alice' > [bob:master:(1) 0.013010] [jmsg/INFO] Received mail1! -> [bob:master:(1) 0.013010] [jmsg/INFO] Process slave will be killed. > [bob:master:(1) 0.013010] [jmsg/INFO] Process2 is now killed, should exit now diff --git a/org/simgrid/msg/Process.java b/org/simgrid/msg/Process.java index dc50455e7c..264a843cf3 100644 --- a/org/simgrid/msg/Process.java +++ b/org/simgrid/msg/Process.java @@ -90,11 +90,7 @@ public abstract class Process implements Runnable { /** The arguments of the method function of the process. */ public Vector args; - - /* process synchronization tools */ - private boolean nativeStop = false; - /** * Default constructor (used in ApplicationHandler to initialize it) */ @@ -188,35 +184,13 @@ public abstract class Process implements Runnable { * */ public static native int killAll(int resetPID); - /** - * This method sets a flag to indicate that this thread must be killed. End user must use static method kill - * - * @return - * - */ - public void nativeStop() { - nativeStop = true; - } - /** - * getter for the flag that indicates that this thread must be killed - * - * @return - * - */ - public boolean getNativeStop() { - return nativeStop; - } /** * This method kill a process. * @param process the process to be killed. * */ - public void kill() { - nativeStop(); - Msg.info("Process " + msgName() + " will be killed."); - } - + public native void kill(); /** * Suspends the process by suspending the task on which it was * waiting for the completion. @@ -285,11 +259,6 @@ public abstract class Process implements Runnable { * */ public static native Process currentProcess(); - /** - * Kills a MSG process - * @param process Valid java process to kill - */ - final static native void kill(Process process); /** * Migrates a process to another host. * @@ -359,16 +328,9 @@ public abstract class Process implements Runnable { Msg.info("Unexpected behavior. Stopping now"); System.exit(1); } - catch(ProcessKilled pk) { - if (nativeStop) { + catch(ProcessKilledException pk) { - } - else { - pk.printStackTrace(); - Msg.info("Unexpected behavior. Stopping now"); - System.exit(1); - } - } + } } /** diff --git a/org/simgrid/msg/ProcessKilled.java b/org/simgrid/msg/ProcessKilledException.java similarity index 62% rename from org/simgrid/msg/ProcessKilled.java rename to org/simgrid/msg/ProcessKilledException.java index f032341728..d89e565136 100644 --- a/org/simgrid/msg/ProcessKilled.java +++ b/org/simgrid/msg/ProcessKilledException.java @@ -3,7 +3,9 @@ package org.simgrid.msg; /** This exception class is only used to interrupt the java user code * when the process gets killed by an external event */ -public class ProcessKilled extends RuntimeException { +public class ProcessKilledException extends RuntimeException { private static final long serialVersionUID = 1L; - + public ProcessKilledException(String s) { + super(s); + } } diff --git a/src/jmsg_comm.c b/src/jmsg_comm.c index c56c224f79..27b57c0d39 100644 --- a/src/jmsg_comm.c +++ b/src/jmsg_comm.c @@ -88,21 +88,27 @@ Java_org_simgrid_msg_Comm_test(JNIEnv *env, jobject jcomm) { jxbt_throw_native(env,bprintf("comm is null")); return JNI_FALSE; } - if (MSG_comm_test(comm)) { - MSG_error_t status = MSG_comm_get_status(comm); - if (status == MSG_OK) { - jcomm_bind_task(env,jcomm); - return JNI_TRUE; + TRY { + if (MSG_comm_test(comm)) { + MSG_error_t status = MSG_comm_get_status(comm); + if (status == MSG_OK) { + jcomm_bind_task(env,jcomm); + return JNI_TRUE; + } + else { + //send the correct exception + jcomm_throw(env,status); + return JNI_FALSE; + } } else { - //send the correct exception - jcomm_throw(env,status); return JNI_FALSE; } } - else { - return JNI_FALSE; + CATCH_ANONYMOUS { + } + return JNI_FALSE; } JNIEXPORT void JNICALL Java_org_simgrid_msg_Comm_waitCompletion(JNIEnv *env, jobject jcomm, jdouble timeout) { @@ -111,8 +117,13 @@ Java_org_simgrid_msg_Comm_waitCompletion(JNIEnv *env, jobject jcomm, jdouble tim jxbt_throw_native(env,bprintf("comm is null")); return; } - - MSG_error_t status = MSG_comm_wait(comm,(double)timeout); + MSG_error_t status; + TRY { + status = MSG_comm_wait(comm,(double)timeout); + } + CATCH_ANONYMOUS { + return; + } if (status == MSG_OK) { jcomm_bind_task(env,jcomm); return; diff --git a/src/jmsg_process.c b/src/jmsg_process.c index bdb88c10ba..319294498b 100644 --- a/src/jmsg_process.c +++ b/src/jmsg_process.c @@ -40,17 +40,6 @@ void jprocess_join(jobject jprocess, JNIEnv * env) xbt_os_thread_join(context->thread,NULL); } -void jprocess_exit(jobject jprocess, JNIEnv * env) -{ - jmethodID id = - jxbt_get_smethod(env, "org/simgrid/msg/Process", "interrupt", "()V"); - - if (!id) - return; - - (*env)->CallVoidMethod(env, jprocess, id); -} - void jprocess_start(jobject jprocess, JNIEnv * env) { jmethodID id = @@ -72,16 +61,13 @@ m_process_t jprocess_to_native_process(jobject jprocess, JNIEnv * env) XBT_INFO("Can't find bind field in Process"); return NULL; } - return (m_process_t) (long) (*env)->GetLongField(env, jprocess, id); } void jprocess_bind(jobject jprocess, m_process_t process, JNIEnv * env) { jfieldID id = jxbt_get_sfield(env, "org/simgrid/msg/Process", "bind", "J"); - if (!id) - return; - + xbt_assert((id != NULL), "field bind not found in org/simgrid/msg/Process"); (*env)->SetLongField(env, jprocess, id, (jlong) (long) (process)); } @@ -189,15 +175,14 @@ Java_org_simgrid_msg_Process_create(JNIEnv * env, 0,NULL,NULL); MSG_process_set_data(process,&process); + /* bind the java process instance to the native process */ + jprocess_bind(jprocess, process, env); /* release our reference to the process name (variable name becomes invalid) */ //FIXME : This line should be uncommented but with mac it doesn't work. BIG WARNING //(*env)->ReleaseStringUTFChars(env, jname, name); (*env)->ReleaseStringUTFChars(env, jhostname, hostname); - /* bind the java process instance to the native process */ - jprocess_bind(jprocess, process, env); - /* sets the PID and the PPID of the process */ (*env)->SetIntField(env, jprocess, jprocess_field_Process_pid,(jint) MSG_process_get_PID(process)); (*env)->SetIntField(env, jprocess, jprocess_field_Process_ppid, (jint) MSG_process_get_PPID(process)); @@ -330,21 +315,20 @@ Java_org_simgrid_msg_Process_waitFor(JNIEnv * env, jobject jprocess, } JNIEXPORT void JNICALL -Java_org_simgrid_msg_Process_kill(JNIEnv * env, jclass cls, +Java_org_simgrid_msg_Process_kill(JNIEnv * env, jobject jprocess) { - /* get the native instances from the java ones */ + /* get the native instances from the java ones */ m_process_t process = jprocess_to_native_process(jprocess, env); - if (!process) { jxbt_throw_notbound(env, "process", jprocess); return; } + /* Sets the "killed" flag to kill the process on the next unschedule */ + smx_ctx_java_t context = (smx_ctx_java_t)MSG_process_get_smx_ctx(process); + context->killed = 1; - /* kill the native process (this wrapper is call by the destructor of the java - * process instance) - */ - MSG_process_kill(process); + MSG_process_kill(process); } JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_migrate(JNIEnv * env, diff --git a/src/jmsg_process.h b/src/jmsg_process.h index 0f5c41b0ca..2623910d95 100644 --- a/src/jmsg_process.h +++ b/src/jmsg_process.h @@ -67,19 +67,6 @@ void jprocess_join(jobject jprocess, JNIEnv * env); */ void jprocess_start(jobject jprocess, JNIEnv * env); -/** - * This function forces the java process to stop. - * - * @param jprocess The java process to stop. - * @param env The env of the current thread - * - * @exception If the class Process is not found the function throws - * the ClassNotFoundException. If the methos stop() of - * this class is not found the function throws the exception - * NotSuchMethodException. - */ -void jprocess_exit(jobject jprocess, JNIEnv * env); - /** * This function associated a native process to a java process instance. * @@ -236,7 +223,7 @@ JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_waitFor * Signature (Lsimgrid/msg/Process;)V */ JNIEXPORT void JNICALL Java_org_simgrid_msg_Process_kill - (JNIEnv *, jclass, jobject); + (JNIEnv *, jobject); /* * Class org_simgrid_msg_Process diff --git a/src/jmsg_task.c b/src/jmsg_task.c index d0ac22e8ae..6c485181cc 100644 --- a/src/jmsg_task.c +++ b/src/jmsg_task.c @@ -426,8 +426,12 @@ Java_org_simgrid_msg_Task_receive(JNIEnv * env, jclass cls, } alias = (*env)->GetStringUTFChars(env, jalias, 0); - - rv = MSG_task_receive_ext(&task, alias, (double) jtimeout, host); + TRY { + rv = MSG_task_receive_ext(&task, alias, (double) jtimeout, host); + } + CATCH_ANONYMOUS { + return NULL; + } if (rv != MSG_OK) { switch (rv) { case MSG_TIMEOUT: @@ -576,9 +580,12 @@ Java_org_simgrid_msg_Task_listen(JNIEnv * env, jclass cls, int rv; alias = (*env)->GetStringUTFChars(env, jalias, 0); - - rv = MSG_task_listen(alias); - + TRY { + rv = MSG_task_listen(alias); + } + CATCH_ANONYMOUS { + return 0; + } (*env)->ReleaseStringUTFChars(env, jalias, alias); return (jboolean) rv; @@ -598,9 +605,12 @@ Java_org_simgrid_msg_Task_listenFromHost(JNIEnv * env, jclass cls, return -1; } alias = (*env)->GetStringUTFChars(env, jalias, 0); - - rv = MSG_task_listen_from_host(alias, host); - + TRY { + rv = MSG_task_listen_from_host(alias, host); + } + CATCH_ANONYMOUS { + return 0; + } (*env)->ReleaseStringUTFChars(env, jalias, alias); return (jint) rv; @@ -613,9 +623,12 @@ Java_org_simgrid_msg_Task_listenFrom(JNIEnv * env, jclass cls, int rv; const char *alias = (*env)->GetStringUTFChars(env, jalias, 0); - - rv = MSG_task_listen_from(alias); - + TRY { + rv = MSG_task_listen_from(alias); + } + CATCH_ANONYMOUS { + return 0; + } (*env)->ReleaseStringUTFChars(env, jalias, alias); return (jint) rv; diff --git a/src/jxbt_utilities.c b/src/jxbt_utilities.c index a5963656f5..fb31732104 100644 --- a/src/jxbt_utilities.c +++ b/src/jxbt_utilities.c @@ -201,7 +201,7 @@ jfieldID jxbt_get_sfield(JNIEnv * env, const char *classname, /* ***************** */ /* EXCEPTION RAISING */ /* ***************** */ -static void jxbt_throw_by_name(JNIEnv * env, const char *name, char *msg) +void jxbt_throw_by_name(JNIEnv * env, const char *name, char *msg) { jclass cls = (*env)->FindClass(env, name); diff --git a/src/jxbt_utilities.h b/src/jxbt_utilities.h index 3b0bb4f468..c395041c5e 100644 --- a/src/jxbt_utilities.h +++ b/src/jxbt_utilities.h @@ -65,6 +65,8 @@ jfieldID jxbt_get_sfield(JNIEnv * env, const char *classname, jxbt_throw_task_cancelled(env,detail); \ } } while (0) +/* Throws an exception according to its name */ +void jxbt_throw_by_name(JNIEnv * env, const char *name, char *msg); /** Thrown on internal error of this layer, or on problem with JNI */ void jxbt_throw_jni(JNIEnv * env, const char *msg); /** Thrown when using an object not bound to a native one where it should, or reverse (kinda JNI issue) */ diff --git a/src/smx_context_java.c b/src/smx_context_java.c index 1c3b80cf53..a31c9519d3 100644 --- a/src/smx_context_java.c +++ b/src/smx_context_java.c @@ -9,6 +9,7 @@ #include #include +#include #include "smx_context_java.h" #include "jxbt_utilities.h" #include "xbt/dynar.h" @@ -74,6 +75,7 @@ smx_ctx_java_factory_create_context(xbt_main_func_t code, int argc, context->jprocess = (jobject) code; context->begin = xbt_os_sem_init(0); context->end = xbt_os_sem_init(0); + context->killed = 0; context->thread = xbt_os_thread_create(NULL,smx_ctx_java_thread_run,context,NULL); } else { @@ -99,7 +101,6 @@ static void* smx_ctx_java_thread_run(void *data) { jmethodID id = jxbt_get_smethod(env, "org/simgrid/msg/Process", "run", "()V"); xbt_assert( (id != NULL), "Method not found..."); (*env)->CallVoidMethod(env, context->jprocess, id); - smx_ctx_java_stop((smx_context_t)context); return NULL; @@ -125,15 +126,24 @@ void smx_ctx_java_stop(smx_context_t context) xbt_assert(context == my_current_context, "The context to stop must be the current one"); /* I am the current process and I am dying */ - smx_ctx_base_stop(context); - /* detach the thread and kills it */ - JNIEnv *env = ctx_java->jenv; - (*env)->DeleteGlobalRef(env,ctx_java->jprocess); - JavaVM *jvm = get_current_vm(); - jint error = (*jvm)->DetachCurrentThread(jvm); - xbt_assert((error == JNI_OK), "The thread couldn't be detached."); - xbt_os_sem_release(((smx_ctx_java_t)context)->end); - xbt_os_thread_exit(NULL); + if (ctx_java->killed == 1) { + ctx_java->killed = 0; + JNIEnv *env = get_current_thread_env(); + jxbt_throw_by_name(env, "org/simgrid/msg/ProcessKilledException", bprintf("Process killed :)")); + THROWF(cancel_error, 0, "process cancelled"); + } + else { + smx_ctx_base_stop(context); + /* detach the thread and kills it */ + JNIEnv *env = ctx_java->jenv; + (*env)->DeleteGlobalRef(env,ctx_java->jprocess); + JavaVM *jvm = get_current_vm(); + jint error = (*jvm)->DetachCurrentThread(jvm); + xbt_assert((error == JNI_OK), "The thread couldn't be detached."); + xbt_os_sem_release(((smx_ctx_java_t)context)->end); + xbt_os_thread_exit(NULL); + + } } static void smx_ctx_java_suspend(smx_context_t context) @@ -148,7 +158,7 @@ static void smx_ctx_java_resume(smx_context_t new_context) { XBT_DEBUG("XXXX Context Resume\n"); smx_ctx_java_t ctx_java = (smx_ctx_java_t) new_context; - xbt_os_sem_release(ctx_java->begin); + xbt_os_sem_release(ctx_java->begin); xbt_os_sem_acquire(ctx_java->end); } diff --git a/src/smx_context_java.h b/src/smx_context_java.h index 4142bf120c..d0578f00dc 100644 --- a/src/smx_context_java.h +++ b/src/smx_context_java.h @@ -23,6 +23,7 @@ typedef struct s_smx_ctx_java { xbt_os_thread_t thread; xbt_os_sem_t begin; /* this semaphore is used to schedule/yield the process */ xbt_os_sem_t end; /* this semaphore is used to schedule/unschedule the process */ + int killed; } s_smx_ctx_java_t, *smx_ctx_java_t; void SIMIX_ctx_java_factory_init(smx_context_factory_t *factory);