1 /* 2 * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.misc; 27 28 import java.util.concurrent.locks.ReentrantLock; 29 30 /** 31 * This class is used to prevent multiple calling of g_thread_init () 32 * and gdk_thread_init (). 33 * 34 * Since version 2.24 of GLib, calling g_thread_init () multiple times is 35 * allowed, but it will crash for older versions. There are two ways to 36 * find out if g_thread_init () has been called: 37 * g_thread_get_initialized (), but it was introduced in 2.20 38 * g_thread_supported (), but it is a macro and cannot be loaded with dlsym. 39 * 40 * usage: 41 * <pre> 42 * lock(); 43 * try { 44 * if (!getAndSetInitializationNeededFlag()) { 45 * //call to g_thread_init(); 46 * //call to gdk_thread_init(); 47 * } 48 * } finally { 49 * unlock(); 50 * } 51 * </pre> 52 */ 53 public final class GThreadHelper { 54 55 private static final ReentrantLock LOCK = new ReentrantLock(); 56 private static boolean isGThreadInitialized = false; 57 58 /** 59 * Acquires the lock. 60 */ 61 public static void lock() { 62 LOCK.lock(); 63 } 64 65 /** 66 * Releases the lock. 67 */ 68 public static void unlock() { 69 LOCK.unlock(); 70 } 71 72 /** 73 * Gets current value of initialization flag and sets it to {@code true}. 74 * MUST be called under the lock. 75 * 76 * A return value of {@code false} indicates that the calling code 77 * should call the g_thread_init() and gdk_thread_init() functions 78 * before releasing the lock. 79 * 80 * @return {@code true} if initialization has been completed. 81 */ 82 public static boolean getAndSetInitializationNeededFlag() { 83 boolean ret = isGThreadInitialized; 84 isGThreadInitialized = true; 85 return ret; 86 } 87 }