* testsuite/libgomp.fortran/vla7.f90: Add -w to options.
[official-gcc.git] / libjava / java / lang / Runtime.java
blob519b4ac8c5ef7a081099441abf19706dbf5ab784
1 /* Runtime.java -- access to the VM process
2 Copyright (C) 1998, 2002, 2003, 2004, 2005, 2006 Free Software Foundation
4 This file is part of GNU Classpath.
6 GNU Classpath is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2, or (at your option)
9 any later version.
11 GNU Classpath is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GNU Classpath; see the file COPYING. If not, write to the
18 Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
19 02110-1301 USA.
21 Linking this library statically or dynamically with other modules is
22 making a combined work based on this library. Thus, the terms and
23 conditions of the GNU General Public License cover the whole
24 combination.
26 As a special exception, the copyright holders of this library give you
27 permission to link this library with independent modules to produce an
28 executable, regardless of the license terms of these independent
29 modules, and to copy and distribute the resulting executable under
30 terms of your choice, provided that you also meet, for each linked
31 independent module, the terms and conditions of the license of that
32 module. An independent module is a module which is not derived from
33 or based on this library. If you modify this library, you may extend
34 this exception to your version of the library, but you are not
35 obligated to do so. If you do not wish to do so, delete this
36 exception statement from your version. */
39 package java.lang;
41 import gnu.classpath.SystemProperties;
43 import java.io.File;
44 import java.io.IOException;
45 import java.io.InputStream;
46 import java.io.OutputStream;
47 import java.util.HashSet;
48 import java.util.Iterator;
49 import java.util.Set;
50 import java.util.StringTokenizer;
52 /**
53 * Runtime represents the Virtual Machine.
55 * @author John Keiser
56 * @author Eric Blake (ebb9@email.byu.edu)
57 * @author Jeroen Frijters
59 // No idea why this class isn't final, since you can't build a subclass!
60 public class Runtime
62 /**
63 * The library path, to search when loading libraries. We can also safely use
64 * this as a lock for synchronization.
66 private final String[] libpath;
68 static
70 init();
73 /**
74 * The thread that started the exit sequence. Access to this field must
75 * be thread-safe; lock on libpath to avoid deadlock with user code.
76 * <code>runFinalization()</code> may want to look at this to see if ALL
77 * finalizers should be run, because the virtual machine is about to halt.
79 private Thread exitSequence;
81 /**
82 * All shutdown hooks. This is initialized lazily, and set to null once all
83 * shutdown hooks have run. Access to this field must be thread-safe; lock
84 * on libpath to avoid deadlock with user code.
86 private Set shutdownHooks;
88 /** True if we should finalize on exit. */
89 private boolean finalizeOnExit;
91 /**
92 * The one and only runtime instance.
94 private static final Runtime current = new Runtime();
96 /**
97 * Not instantiable by a user, this should only create one instance.
99 private Runtime()
101 if (current != null)
102 throw new InternalError("Attempt to recreate Runtime");
104 // We don't use libpath in the libgcj implementation. We still
105 // set it to something to allow the various synchronizations to
106 // work.
107 libpath = new String[0];
111 * Get the current Runtime object for this JVM. This is necessary to access
112 * the many instance methods of this class.
114 * @return the current Runtime object
116 public static Runtime getRuntime()
118 return current;
122 * Exit the Java runtime. This method will either throw a SecurityException
123 * or it will never return. The status code is returned to the system; often
124 * a non-zero status code indicates an abnormal exit. Of course, there is a
125 * security check, <code>checkExit(status)</code>.
127 * <p>First, all shutdown hooks are run, in unspecified order, and
128 * concurrently. Next, if finalization on exit has been enabled, all pending
129 * finalizers are run. Finally, the system calls <code>halt</code>.</p>
131 * <p>If this is run a second time after shutdown has already started, there
132 * are two actions. If shutdown hooks are still executing, it blocks
133 * indefinitely. Otherwise, if the status is nonzero it halts immediately;
134 * if it is zero, it blocks indefinitely. This is typically called by
135 * <code>System.exit</code>.</p>
137 * @param status the status to exit with
138 * @throws SecurityException if permission is denied
139 * @see #addShutdownHook(Thread)
140 * @see #runFinalizersOnExit(boolean)
141 * @see #runFinalization()
142 * @see #halt(int)
144 public void exit(int status)
146 SecurityManager sm = SecurityManager.current; // Be thread-safe!
147 if (sm != null)
148 sm.checkExit(status);
150 if (runShutdownHooks())
151 halt(status);
153 // Someone else already called runShutdownHooks().
154 // Make sure we are not/no longer in the shutdownHooks set.
155 // And wait till the thread that is calling runShutdownHooks() finishes.
156 synchronized (libpath)
158 if (shutdownHooks != null)
160 shutdownHooks.remove(Thread.currentThread());
161 // Interrupt the exit sequence thread, in case it was waiting
162 // inside a join on our thread.
163 exitSequence.interrupt();
164 // Shutdown hooks are still running, so we clear status to
165 // make sure we don't halt.
166 status = 0;
170 // If exit() is called again after the shutdown hooks have run, but
171 // while finalization for exit is going on and the status is non-zero
172 // we halt immediately.
173 if (status != 0)
174 halt(status);
176 while (true)
179 exitSequence.join();
181 catch (InterruptedException e)
183 // Ignore, we've suspended indefinitely to let all shutdown
184 // hooks complete, and to let any non-zero exits through, because
185 // this is a duplicate call to exit(0).
190 * On first invocation, run all the shutdown hooks and return true.
191 * Any subsequent invocations will simply return false.
192 * Note that it is package accessible so that VMRuntime can call it
193 * when VM exit is not triggered by a call to Runtime.exit().
195 * @return was the current thread the first one to call this method?
197 boolean runShutdownHooks()
199 boolean first = false;
200 synchronized (libpath) // Synch on libpath, not this, to avoid deadlock.
202 if (exitSequence == null)
204 first = true;
205 exitSequence = Thread.currentThread();
206 if (shutdownHooks != null)
208 Iterator i = shutdownHooks.iterator();
209 while (i.hasNext()) // Start all shutdown hooks.
212 ((Thread) i.next()).start();
214 catch (IllegalThreadStateException e)
216 i.remove();
221 if (first)
223 if (shutdownHooks != null)
225 // Check progress of all shutdown hooks. As a hook completes,
226 // remove it from the set. If a hook calls exit, it removes
227 // itself from the set, then waits indefinitely on the
228 // exitSequence thread. Once the set is empty, set it to null to
229 // signal all finalizer threads that halt may be called.
230 while (true)
232 Thread[] hooks;
233 synchronized (libpath)
235 hooks = new Thread[shutdownHooks.size()];
236 shutdownHooks.toArray(hooks);
238 if (hooks.length == 0)
239 break;
240 for (int i = 0; i < hooks.length; i++)
244 synchronized (libpath)
246 if (!shutdownHooks.contains(hooks[i]))
247 continue;
249 hooks[i].join();
250 synchronized (libpath)
252 shutdownHooks.remove(hooks[i]);
255 catch (InterruptedException x)
257 // continue waiting on the next thread
261 synchronized (libpath)
263 shutdownHooks = null;
266 // Run finalization on all finalizable objects (even if they are
267 // still reachable).
268 runFinalizationForExit();
270 return first;
274 * Register a new shutdown hook. This is invoked when the program exits
275 * normally (because all non-daemon threads ended, or because
276 * <code>System.exit</code> was invoked), or when the user terminates
277 * the virtual machine (such as by typing ^C, or logging off). There is
278 * a security check to add hooks,
279 * <code>RuntimePermission("shutdownHooks")</code>.
281 * <p>The hook must be an initialized, but unstarted Thread. The threads
282 * are run concurrently, and started in an arbitrary order; and user
283 * threads or daemons may still be running. Once shutdown hooks have
284 * started, they must all complete, or else you must use <code>halt</code>,
285 * to actually finish the shutdown sequence. Attempts to modify hooks
286 * after shutdown has started result in IllegalStateExceptions.</p>
288 * <p>It is imperative that you code shutdown hooks defensively, as you
289 * do not want to deadlock, and have no idea what other hooks will be
290 * running concurrently. It is also a good idea to finish quickly, as the
291 * virtual machine really wants to shut down!</p>
293 * <p>There are no guarantees that such hooks will run, as there are ways
294 * to forcibly kill a process. But in such a drastic case, shutdown hooks
295 * would do little for you in the first place.</p>
297 * @param hook an initialized, unstarted Thread
298 * @throws IllegalArgumentException if the hook is already registered or run
299 * @throws IllegalStateException if the virtual machine is already in
300 * the shutdown sequence
301 * @throws SecurityException if permission is denied
302 * @since 1.3
303 * @see #removeShutdownHook(Thread)
304 * @see #exit(int)
305 * @see #halt(int)
307 public void addShutdownHook(Thread hook)
309 SecurityManager sm = SecurityManager.current; // Be thread-safe!
310 if (sm != null)
311 sm.checkPermission(new RuntimePermission("shutdownHooks"));
312 if (hook.isAlive() || hook.getThreadGroup() == null)
313 throw new IllegalArgumentException("The hook thread " + hook + " must not have been already run or started");
314 synchronized (libpath)
316 if (exitSequence != null)
317 throw new IllegalStateException("The Virtual Machine is exiting. It is not possible anymore to add any hooks");
318 if (shutdownHooks == null)
319 shutdownHooks = new HashSet(); // Lazy initialization.
320 if (! shutdownHooks.add(hook))
321 throw new IllegalArgumentException(hook.toString() + " had already been inserted");
326 * De-register a shutdown hook. As when you registered it, there is a
327 * security check to remove hooks,
328 * <code>RuntimePermission("shutdownHooks")</code>.
330 * @param hook the hook to remove
331 * @return true if the hook was successfully removed, false if it was not
332 * registered in the first place
333 * @throws IllegalStateException if the virtual machine is already in
334 * the shutdown sequence
335 * @throws SecurityException if permission is denied
336 * @since 1.3
337 * @see #addShutdownHook(Thread)
338 * @see #exit(int)
339 * @see #halt(int)
341 public boolean removeShutdownHook(Thread hook)
343 SecurityManager sm = SecurityManager.current; // Be thread-safe!
344 if (sm != null)
345 sm.checkPermission(new RuntimePermission("shutdownHooks"));
346 synchronized (libpath)
348 if (exitSequence != null)
349 throw new IllegalStateException();
350 if (shutdownHooks != null)
351 return shutdownHooks.remove(hook);
353 return false;
357 * Forcibly terminate the virtual machine. This call never returns. It is
358 * much more severe than <code>exit</code>, as it bypasses all shutdown
359 * hooks and initializers. Use caution in calling this! Of course, there is
360 * a security check, <code>checkExit(status)</code>.
362 * @param status the status to exit with
363 * @throws SecurityException if permission is denied
364 * @since 1.3
365 * @see #exit(int)
366 * @see #addShutdownHook(Thread)
368 public void halt(int status)
370 SecurityManager sm = SecurityManager.current; // Be thread-safe!
371 if (sm != null)
372 sm.checkExit(status);
373 exitInternal(status);
377 * Tell the VM to run the finalize() method on every single Object before
378 * it exits. Note that the JVM may still exit abnormally and not perform
379 * this, so you still don't have a guarantee. And besides that, this is
380 * inherently unsafe in multi-threaded code, as it may result in deadlock
381 * as multiple threads compete to manipulate objects. This value defaults to
382 * <code>false</code>. There is a security check, <code>checkExit(0)</code>.
384 * @param finalizeOnExit whether to finalize all Objects on exit
385 * @throws SecurityException if permission is denied
386 * @see #exit(int)
387 * @see #gc()
388 * @since 1.1
389 * @deprecated never rely on finalizers to do a clean, thread-safe,
390 * mop-up from your code
392 public static void runFinalizersOnExit(boolean finalizeOnExit)
394 SecurityManager sm = SecurityManager.current; // Be thread-safe!
395 if (sm != null)
396 sm.checkExit(0);
397 current.finalizeOnExit = finalizeOnExit;
401 * Create a new subprocess with the specified command line. Calls
402 * <code>exec(cmdline, null, null)</code>. A security check is performed,
403 * <code>checkExec</code>.
405 * @param cmdline the command to call
406 * @return the Process object
407 * @throws SecurityException if permission is denied
408 * @throws IOException if an I/O error occurs
409 * @throws NullPointerException if cmdline is null
410 * @throws IndexOutOfBoundsException if cmdline is ""
412 public Process exec(String cmdline) throws IOException
414 return exec(cmdline, null, null);
418 * Create a new subprocess with the specified command line and environment.
419 * If the environment is null, the process inherits the environment of
420 * this process. Calls <code>exec(cmdline, env, null)</code>. A security
421 * check is performed, <code>checkExec</code>.
423 * @param cmdline the command to call
424 * @param env the environment to use, in the format name=value
425 * @return the Process object
426 * @throws SecurityException if permission is denied
427 * @throws IOException if an I/O error occurs
428 * @throws NullPointerException if cmdline is null, or env has null entries
429 * @throws IndexOutOfBoundsException if cmdline is ""
431 public Process exec(String cmdline, String[] env) throws IOException
433 return exec(cmdline, env, null);
437 * Create a new subprocess with the specified command line, environment, and
438 * working directory. If the environment is null, the process inherits the
439 * environment of this process. If the directory is null, the process uses
440 * the current working directory. This splits cmdline into an array, using
441 * the default StringTokenizer, then calls
442 * <code>exec(cmdArray, env, dir)</code>. A security check is performed,
443 * <code>checkExec</code>.
445 * @param cmdline the command to call
446 * @param env the environment to use, in the format name=value
447 * @param dir the working directory to use
448 * @return the Process object
449 * @throws SecurityException if permission is denied
450 * @throws IOException if an I/O error occurs
451 * @throws NullPointerException if cmdline is null, or env has null entries
452 * @throws IndexOutOfBoundsException if cmdline is ""
453 * @since 1.3
455 public Process exec(String cmdline, String[] env, File dir)
456 throws IOException
458 StringTokenizer t = new StringTokenizer(cmdline);
459 String[] cmd = new String[t.countTokens()];
460 for (int i = 0; i < cmd.length; i++)
461 cmd[i] = t.nextToken();
462 return exec(cmd, env, dir);
466 * Create a new subprocess with the specified command line, already
467 * tokenized. Calls <code>exec(cmd, null, null)</code>. A security check
468 * is performed, <code>checkExec</code>.
470 * @param cmd the command to call
471 * @return the Process object
472 * @throws SecurityException if permission is denied
473 * @throws IOException if an I/O error occurs
474 * @throws NullPointerException if cmd is null, or has null entries
475 * @throws IndexOutOfBoundsException if cmd is length 0
477 public Process exec(String[] cmd) throws IOException
479 return exec(cmd, null, null);
483 * Create a new subprocess with the specified command line, already
484 * tokenized, and specified environment. If the environment is null, the
485 * process inherits the environment of this process. Calls
486 * <code>exec(cmd, env, null)</code>. A security check is performed,
487 * <code>checkExec</code>.
489 * @param cmd the command to call
490 * @param env the environment to use, in the format name=value
491 * @return the Process object
492 * @throws SecurityException if permission is denied
493 * @throws IOException if an I/O error occurs
494 * @throws NullPointerException if cmd is null, or cmd or env has null
495 * entries
496 * @throws IndexOutOfBoundsException if cmd is length 0
498 public Process exec(String[] cmd, String[] env) throws IOException
500 return exec(cmd, env, null);
504 * Create a new subprocess with the specified command line, already
505 * tokenized, and the specified environment and working directory. If the
506 * environment is null, the process inherits the environment of this
507 * process. If the directory is null, the process uses the current working
508 * directory. A security check is performed, <code>checkExec</code>.
510 * @param cmd the command to call
511 * @param env the environment to use, in the format name=value
512 * @param dir the working directory to use
513 * @return the Process object
514 * @throws SecurityException if permission is denied
515 * @throws IOException if an I/O error occurs
516 * @throws NullPointerException if cmd is null, or cmd or env has null
517 * entries
518 * @throws IndexOutOfBoundsException if cmd is length 0
519 * @since 1.3
521 public Process exec(String[] cmd, String[] env, File dir)
522 throws IOException
524 SecurityManager sm = SecurityManager.current; // Be thread-safe!
525 if (sm != null)
526 sm.checkExec(cmd[0]);
527 return execInternal(cmd, env, dir);
531 * Returns the number of available processors currently available to the
532 * virtual machine. This number may change over time; so a multi-processor
533 * program want to poll this to determine maximal resource usage.
535 * @return the number of processors available, at least 1
537 public native int availableProcessors();
540 * Find out how much memory is still free for allocating Objects on the heap.
542 * @return the number of bytes of free memory for more Objects
544 public native long freeMemory();
547 * Find out how much memory total is available on the heap for allocating
548 * Objects.
550 * @return the total number of bytes of memory for Objects
552 public native long totalMemory();
555 * Returns the maximum amount of memory the virtual machine can attempt to
556 * use. This may be <code>Long.MAX_VALUE</code> if there is no inherent
557 * limit (or if you really do have a 8 exabyte memory!).
559 * @return the maximum number of bytes the virtual machine will attempt
560 * to allocate
562 public native long maxMemory();
565 * Run the garbage collector. This method is more of a suggestion than
566 * anything. All this method guarantees is that the garbage collector will
567 * have "done its best" by the time it returns. Notice that garbage
568 * collection takes place even without calling this method.
570 public native void gc();
573 * Run finalization on all Objects that are waiting to be finalized. Again,
574 * a suggestion, though a stronger one than {@link #gc()}. This calls the
575 * <code>finalize</code> method of all objects waiting to be collected.
577 * @see #finalize()
579 public native void runFinalization();
582 * Tell the VM to trace every bytecode instruction that executes (print out
583 * a trace of it). No guarantees are made as to where it will be printed,
584 * and the VM is allowed to ignore this request.
586 * @param on whether to turn instruction tracing on
588 public native void traceInstructions(boolean on);
591 * Tell the VM to trace every method call that executes (print out a trace
592 * of it). No guarantees are made as to where it will be printed, and the
593 * VM is allowed to ignore this request.
595 * @param on whether to turn method tracing on
597 public native void traceMethodCalls(boolean on);
600 * Load a native library using the system-dependent filename. This is similar
601 * to loadLibrary, except the only name mangling done is inserting "_g"
602 * before the final ".so" if the VM was invoked by the name "java_g". There
603 * may be a security check, of <code>checkLink</code>.
605 * @param filename the file to load
606 * @throws SecurityException if permission is denied
607 * @throws UnsatisfiedLinkError if the library is not found
609 public void load(String filename)
611 SecurityManager sm = SecurityManager.current; // Be thread-safe!
612 if (sm != null)
613 sm.checkLink(filename);
614 _load(filename, false);
618 * Load a native library using a system-independent "short name" for the
619 * library. It will be transformed to a correct filename in a
620 * system-dependent manner (for example, in Windows, "mylib" will be turned
621 * into "mylib.dll"). This is done as follows: if the context that called
622 * load has a ClassLoader cl, then <code>cl.findLibrary(libpath)</code> is
623 * used to convert the name. If that result was null, or there was no class
624 * loader, this searches each directory of the system property
625 * <code>java.library.path</code> for a file named
626 * <code>System.mapLibraryName(libname)</code>. There may be a security
627 * check, of <code>checkLink</code>.
629 * @param libname the library to load
631 * @throws SecurityException if permission is denied
632 * @throws UnsatisfiedLinkError if the library is not found
634 * @see System#mapLibraryName(String)
635 * @see ClassLoader#findLibrary(String)
637 public void loadLibrary(String libname)
639 // This is different from the Classpath implementation, but I
640 // believe it is more correct.
641 SecurityManager sm = SecurityManager.current; // Be thread-safe!
642 if (sm != null)
643 sm.checkLink(libname);
644 _load(libname, true);
648 * Return a localized version of this InputStream, meaning all characters
649 * are localized before they come out the other end.
651 * @param in the stream to localize
652 * @return the localized stream
653 * @deprecated <code>InputStreamReader</code> is the preferred way to read
654 * local encodings
656 public InputStream getLocalizedInputStream(InputStream in)
658 return in;
662 * Return a localized version of this OutputStream, meaning all characters
663 * are localized before they are sent to the other end.
665 * @param out the stream to localize
666 * @return the localized stream
667 * @deprecated <code>OutputStreamWriter</code> is the preferred way to write
668 * local encodings
670 public OutputStream getLocalizedOutputStream(OutputStream out)
672 return out;
676 * Native method that actually shuts down the virtual machine.
678 * @param status the status to end the process with
680 native void exitInternal(int status);
683 * Load a file. If it has already been loaded, do nothing. The name has
684 * already been mapped to a true filename.
686 * @param filename the file to load
687 * @param do_search True if we should search the load path for the file
689 native void _load(String filename, boolean do_search);
692 *This is a helper function for the ClassLoader which can load
693 * compiled libraries. Returns true if library (which is just the
694 * base name -- path searching is done by this function) was loaded,
695 * false otherwise.
697 native boolean loadLibraryInternal(String libname);
700 * A helper for Runtime static initializer which does some internal native
701 * initialization.
703 private static native void init ();
706 * Run finalizers when exiting.
708 private native void runFinalizationForExit();
711 * Map a system-independent "short name" to the full file name, and append
712 * it to the path.
713 * XXX This method is being replaced by System.mapLibraryName.
715 * @param pathname the path
716 * @param libname the short version of the library name
717 * @return the full filename
719 static native String nativeGetLibname(String pathname, String libname);
722 * Execute a process. The command line has already been tokenized, and
723 * the environment should contain name=value mappings. If directory is null,
724 * use the current working directory; otherwise start the process in that
725 * directory.
727 * @param cmd the non-null command tokens
728 * @param env the non-null environment setup
729 * @param dir the directory to use, may be null
730 * @return the newly created process
731 * @throws NullPointerException if cmd or env have null elements
732 * @throws IOException if the exec fails
734 native Process execInternal(String[] cmd, String[] env, File dir)
735 throws IOException;
736 } // class Runtime