|
Java example source code file (awt_GDIObject.cpp)
The awt_GDIObject.cpp Java example source code/* * Copyright (c) 2005, 2006, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ #include "awt_GDIObject.h" /** * These methods work around a bug in Windows where allocating * the max number of GDI Objects (HDC, Pen, Brush, etc.) will cause the * application and desktop to become unusable. The workaround * ensures we never reach this maximum, by refcounting * HDC, Pen, and Brush objects that are active. We increment the refcount * when we create these objects and decrement the * refcount when we release them, so that our numCurrentObjects * counter should always equal the number of unreleased objects. * We only do this for HDC, Pen, and Brush because these are the only GDI * objects that may grow without bound in our implementation (we cache * these objects per thread, so a growing number of threads may have * unique HDC/Pen/Brush objects per thread and might approach the maximum). * Also, we do not count objects allocated on a temporary basis (such as * the many calls to GetDC() in our code, followed quickly by ReleaseDC()); * we only care about long-lived GDI objects that might bloat our total * object usage. */ /** * Default GDI Object limit for win2k and XP is 10,000 * Set our limit much lower than that to allow a buffer for objects * created beyond the per-thread HDC/Brush/Pen objects we are * counting here, including objects created by the overall process * (which could include the browser, in the case of applets) */ #define MAX_GDI_OBJECTS 9000 // Static initialization of these globals used in AwtGDIObject int AwtGDIObject::numCurrentObjects = 0; // this variable will never be deleted. initialized below with SafeCreate. CriticalSection* AwtGDIObject::objectCounterLock = NULL; int AwtGDIObject::maxGDIObjects = GetMaxGDILimit(); /** * Sets up max GDI limit; we query the registry key that * defines this value on WindowsXP and Windows2000. * If we fail here, we will use the default value * MAX_GDI_OBJECTS as a fallback value. This is not unreasonable - * it seems unlikely that many people would change this * registry key setting. * NOTE: This function is called automatically at startup to * set the value of maxGDIObjects; it should not be necessary to * call this function from anywhere else. Think of it like a static * block in Java. */ int AwtGDIObject::GetMaxGDILimit() { int limit = MAX_GDI_OBJECTS; HKEY hKey = NULL; DWORD ret = RegOpenKeyEx(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Windows", 0, KEY_QUERY_VALUE, &hKey); if (ret == ERROR_SUCCESS) { DWORD valueLength = 4; DWORD regValue; ret = RegQueryValueEx(hKey, L"GDIProcessHandleQuota", NULL, NULL, (LPBYTE)®Value, &valueLength); if (ret == ERROR_SUCCESS) { // Set limit to 90% of the actual limit to account for other // GDI objects that the process might need limit = (int)(regValue * .9); } else { J2dTraceLn(J2D_TRACE_WARNING, "Problem with RegQueryValueEx in GetMaxGDILimit"); } RegCloseKey(hKey); } else { J2dTraceLn(J2D_TRACE_WARNING, "Problem with RegOpenKeyEx in GetMaxGDILimit"); } return limit; } /** * Increment the object counter to indicate that we are about to * create a new GDI object. If the limit has been reached, skip the * increment and return FALSE to indicate that an object should * not be allocated. */ BOOL AwtGDIObject::IncrementIfAvailable() { BOOL available; CriticalSection* pLock = SafeCreate(objectCounterLock); pLock->Enter(); if (numCurrentObjects < maxGDIObjects) { available = TRUE; ++numCurrentObjects; } else { // First, flush the cache; we may have run out simply because // we have unused colors still reserved in the cache GDIHashtable::flushAll(); // Now check again to see if flushing helped. If not, we really // have run out. if (numCurrentObjects < maxGDIObjects) { available = TRUE; ++numCurrentObjects; } else { available = FALSE; } } pLock->Leave(); return available; } /** * Decrement the counter after releasing a GDI Object */ void AwtGDIObject::Decrement() { CriticalSection* pLock = SafeCreate(objectCounterLock); pLock->Enter(); --numCurrentObjects; pLock->Leave(); } /** * This utility method is called by subclasses of AwtGDIObject * to ensure capacity for an additional GDI object. Failure * results in throwing an AWTException. */ BOOL AwtGDIObject::EnsureGDIObjectAvailability() { if (!IncrementIfAvailable()) { // IncrementIfAvailable flushed the cache but still failed; must // have hit the limit. Throw an exception to indicate the problem. if (jvm != NULL) { JNIEnv* env = (JNIEnv *)JNU_GetEnv(jvm, JNI_VERSION_1_2); if (env != NULL && !safe_ExceptionOccurred(env)) { JNU_ThrowByName(env, "java/awt/AWTError", "Pen/Brush creation failure - " \ "exceeded maximum GDI resources"); } } return FALSE; } return TRUE; } Other Java examples (source code examples)Here is a short list of links related to this Java awt_GDIObject.cpp source code file: |
... this post is sponsored by my books ... | |
#1 New Release! |
FP Best Seller |
Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.
A percentage of advertising revenue from
pages under the /java/jwarehouse
URI on this website is
paid back to open source projects.