Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
*
* Copyright (c) 2000-2010 Oracle and/or its affiliates. All rights reserved.
*
* The contents of this file are subject to the terms of either the GNU
* General Public License Version 2 only ("GPL") or the Common Development
* and Distribution License("CDDL") (collectively, the "License"). You
* may not use this file except in compliance with the License. You can
* obtain a copy of the License at
* https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
* or packager/legal/LICENSE.txt. See the License for the specific
* language governing permissions and limitations under the License.
*
* When distributing the software, include this License Header Notice in each
* file and include the License file at packager/legal/LICENSE.txt.
*
* GPL Classpath Exception:
* Oracle designates this particular file as subject to the "Classpath"
* exception as provided by Oracle in the GPL Version 2 section of the License
* file that accompanied this code.
*
* Modifications:
* If applicable, add the following below the License Header, with the fields
* enclosed by brackets [] replaced by your own identifying information:
* "Portions Copyright [year] [name of copyright owner]"
*
* Contributor(s):
* If you wish your version of this file to be governed by only the CDDL or
* only the GPL Version 2, indicate your decision by adding "[Contributor]
* elects to include this software in this distribution under the [CDDL or GPL
* Version 2] license." If you don't indicate a single choice of license, a
* recipient has the option to distribute your version of this file under
* either the CDDL, the GPL Version 2 or to extend the choice of license to
* its licensees as provided above. However, if you add GPL Version 2 code
* and therefore, elected the GPL Version 2 license, then the option applies
* only if the new code is made subject to such option by the copyright
* holder.
*/
/*
* @(#)HandledObject.hpp 1.6 06/26/07
*/
#ifndef HANDLEDOBJECT_HPP
#define HANDLEDOBJECT_HPP
#include
#include "../error/ErrorCodes.h"
#include "Monitor.hpp"
#include "Object.hpp"
#include "../containers/BasicTypeHashtable.hpp"
/** Instead of void* pointer, we use a 32-bit integer to identify
objects that are passed out by the C shim layer. */
typedef PRInt32 ObjectHandle;
/** So we can ensure that the handle has the proper type, each
subclass of HandledObject, implements the getObjectType() method
which returns one of the following as its type. */
enum HandledObjectType {
// This is the super class for all types except the various message types
UNDEFINED_HANDLED_OBJECT,
TEST_HANDLED_OBJECT,
CONNECTION_OBJECT,
SESSION_OBJECT,
DESTINATION_OBJECT,
MESSAGE_CONSUMER_OBJECT,
MESSAGE_PRODUCER_OBJECT,
PROPERTIES_OBJECT,
// This is the super class for (TEXT|BYTES)_MESSAGE_OBJECT
MESSAGE_OBJECT,
TEXT_MESSAGE_OBJECT,
BYTES_MESSAGE_OBJECT
};
/** This constant specifies that the Handle is invalid. We chose this
value because in debug mode, MSVC sets fields of a deleted class
to this value. */
static const ObjectHandle HANDLED_OBJECT_INVALID_HANDLE = 0xFEEEFEEE;
/** Handles are allocated in the range HANDLED_OBJECT_MIN_HANDLE to
HANDLED_OBJECT_MAX_HANDLE. When HANDLED_OBJECT_MAX_HANDLE -
HANDLED_OBJECT_MIN_HANDLE handles have been allocated, the
allocation rolls over to allocate the first unallocated handle
larger than HANDLED_OBJECT_MIN_HANDLE. These values can be
changed with the following constraints: 1) the total number of
possible handle values should be at least as large as the number
of HandledObjects that will exist at a given time, and 2)
HANDLED_OBJECT_INVALID_HANDLE is not between
HANDLED_OBJECT_MIN_HANDLE and HANDLED_OBJECT_MAX_HANDLE. The
range between these values can be made artificially small to test
the ability of the handle manager to roll over. */
static const ObjectHandle HANDLED_OBJECT_MIN_HANDLE = 100;
static const ObjectHandle HANDLED_OBJECT_MAX_HANDLE = 2000000000;
/**
* This class allows various C++ objects (Connection, MessageConsumer,
* etc.) to be accessible to C programs that use this library. For
* safety and modularity, pointers to these objects are not passed out
* of the library, but instead a 32-bit integer handle is used. All
* of the classes that are exported outside of the library are
* subclasses of HandledObject, which automatically allocates a new
* handle when an object is created and deallocates the handle when it
* is destroyed. It also tries to ensure that no object is deleted
* while an external reference to it exists, but this facility should
* not be relied upon. */
class HandledObject : public Object {
private:
/** This object's handle. A pointer to this object can be retrieved
by looking it up in the static member hashtable
allocatedHandles. */
ObjectHandle objectHandle;
/** True iff this handle should be accessible outside of this
* library. Some objects are not exported outside of the library,
* by setting isExported to FALSE, these objects cannot be accessed
* outside of the library. */
PRBool isExported;
/** The number of pointers (not handles) held by the cshim layer to
* this object. This does not include pointers held by objects
* (e.g. Connection or Session) in the C++ code. This prevents us
* from deleting an object while the external code is active. */
PRInt32 externalReferences;
/** True iff the object has been deleted internally, and should be
* deleted by the cshim layer whenever the last external reference
* is returned */
PRBool deletedInternally;
/* The following 2 variables are added for objects that has opposite
* of deletedInternally memory management semantic
*/
PRBool checkDeletedExternally;
/** True iff the object has been deleted externally, and should be
* deleted whenever the last external reference is returned. It's
* only used when checkDeletedExternally is true */
PRBool deletedExternally;
/**
* If true, create object handle lazily, that is, when export */
PRBool lazy;
void init(PRBool lazy);
public:
/** Constructor */
HandledObject();
HandledObject(PRBool lazy);
/** Destructor. It's made virtual so that subclasses destructors
get called */
virtual ~HandledObject();
/** @return true iff this handle should be accessible outside of
this library */
PRBool getIsExported() const;
/** Returns the 32-bit handle for this object.
* @return the handle for this object */
ObjectHandle getHandle() const;
/** Sets whether or not this object is exported outside of the
* class.
* @param export true iff this handle should be accessible * *
* outside of this library */
MQError setIsExported(const PRBool isExported);
/** For objects that has opposite of deletedInternally
* memory management semantic */
void setCheckDeletedExternally();
/** Each sub class must implement this.
* @return the type of the class (e.g. the subclass of HandledObject) */
virtual HandledObjectType getObjectType() const = 0;
/** Each class that has a super class that can be used in place of
* the object should override this. This is currently only used
* for the message types.
* @return the super type of the class */
virtual HandledObjectType getSuperObjectType() const;
/** If we run out of memory, then allocating a handle for this
* object could fail. If this is the case, we can detect it by calling
* this method after the object is constructed.
*
* @return IMQ_SUCCESS if the object was successfully initialized
* and an error otherwise */
virtual iMQError getInitializationError() const;
/** These are the static members and methods for managing the handles */
private:
/** The next handle to allocated */
static ObjectHandle nextHandle;
/** A hashtable used to translate a handle to an object pointer */
static BasicTypeHashtable * allocatedHandles;
/** A monitor to ensure synchronous access to the other member
variables */
static Monitor handleMonitor;
static PRInt32 numAllocatedHandles;
/** Allocates the next handle to handledObject. This is called from the
* constructor.
*
* @param handledObject the object to allocate a handle for
* @return the handled allocated to handledObject */
static ObjectHandle allocateNextHandle(HandledObject * const handledObject);
/** Deallocates handle. This is called from the destructor.
*
* @param handle the handle to deallocate
* @param handledObject the object that handle refers to.
*/
static void deallocateHandle(const ObjectHandle handle,
const HandledObject * const handledObject);
/** Returns the handle to the object handled by handle.
*
* @param the handle of the object to return
* @retrun the object whose handle is handle
*/
static HandledObject * getObject(const ObjectHandle handle);
public:
/** Tests the HandledObject class */
static iMQError test(const PRInt32 numTests, const PRBool checkAllErrors);
/**
* If there are no outstanding external pointers held to
* handledObject (i.e. externalReferences == 0), then it is deleted.
* Otherwise deletedInternally is set to TRUE, and when
* externalReferences reaches 0, releaseExternalReferences will
* delete the object.
*
* @param handledObject the object to delete
* @return IMQ_SUCCESS if successful and an error otherwise */
static iMQError internallyDelete(HandledObject * handledObject);
/**
* If there are no outstanding external pointers held to
* handledObject (i.e. externalReferences == 0), then it is deleted.
* Otherwise deletedInternally is set to TRUE, and when
* externalReferences reaches 0, releaseExternalReferences will
* delete the object.
*
* @param handledObject the object to delete
* @return IMQ_SUCCESS if successful and an error otherwise */
static iMQError externallyDelete(const ObjectHandle handle);
/**
* Used by the C shim layer to acquire a pointer to the object whose
* handle is handle. This increments externalReferences.
*
* @param handle the handle of the object to acquire the reference for
* @return the object handled by handle. */
static HandledObject * acquireExternalReference(const ObjectHandle handle);
/**
* Used by the C shim layer to release a pointer to the object whose
* handle is handle. This decrements externalReferences.
*
* @param handledObject the object to release the reference for
* @return IMQ_SUCCESS if successful and an error otherwise */
static iMQError releaseExternalReference(HandledObject * handledObject);
};
#endif