blob: 99558f6c1372a6f6bc873a449ef3c1d09505fb06 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.yoko.orb.OB;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.yoko.orb.OB.DispatchRequest;
import org.apache.yoko.orb.OB.DispatchStrategy;
import org.apache.yoko.orb.OB.DispatchStrategyFactory;
import org.apache.yoko.orb.OB.InvalidThreadPool;
import org.apache.yoko.orb.OB.SAME_THREAD;
import org.apache.yoko.orb.OB.THREAD_PER_REQUEST;
import org.apache.yoko.orb.OB.THREAD_POOL;
// ----------------------------------------------------------------------
// DispatchThreadSameThread
// ----------------------------------------------------------------------
class DispatchSameThread_impl extends org.omg.CORBA.LocalObject implements
DispatchStrategy {
DispatchSameThread_impl() {
}
// ------------------------------------------------------------------
// Standard IDL to Java Mapping
// ------------------------------------------------------------------
public int id() {
return SAME_THREAD.value;
}
public org.omg.CORBA.Any info() {
return new org.apache.yoko.orb.CORBA.Any();
}
public void dispatch(DispatchRequest request) {
//
// Invoke the request
//
request.invoke();
}
}
// ----------------------------------------------------------------------
// DispatchThreadPerRequest
// ----------------------------------------------------------------------
class DispatchThreadPerRequest_impl extends org.omg.CORBA.LocalObject implements
DispatchStrategy {
class Dispatcher extends Thread {
private DispatchRequest request_;
Dispatcher(DispatchRequest request) {
super("Yoko:ThreadPerRequest:Dispatcher");
request_ = request;
}
public void run() {
//
// Invoke the request
//
request_.invoke();
}
}
DispatchThreadPerRequest_impl() {
}
// ------------------------------------------------------------------
// Standard IDL to Java Mapping
// ------------------------------------------------------------------
public int id() {
return THREAD_PER_REQUEST.value;
}
public org.omg.CORBA.Any info() {
return new org.apache.yoko.orb.CORBA.Any();
}
public void dispatch(DispatchRequest request) {
try {
Thread t = new Dispatcher(request);
t.start();
} catch (OutOfMemoryError e) {
throw new org.omg.CORBA.TRANSIENT();
}
}
}
// ----------------------------------------------------------------------
// DispatchThreadPool_impl
// ----------------------------------------------------------------------
class DispatchThreadPool_impl extends org.omg.CORBA.LocalObject implements
DispatchStrategy {
private int id_;
private ThreadPool pool_;
// ------------------------------------------------------------------
// Standard IDL to Java Mapping
// ------------------------------------------------------------------
public int id() {
return THREAD_POOL.value;
}
public org.omg.CORBA.Any info() {
org.omg.CORBA.Any any = new org.apache.yoko.orb.CORBA.Any();
any.insert_ulong(id_);
return any;
}
public void dispatch(DispatchRequest request) {
pool_.add(request);
}
// ------------------------------------------------------------------
// Yoko internal functions
// Application programs must not use these functions directly
// ------------------------------------------------------------------
DispatchThreadPool_impl(int id, ThreadPool pool) {
id_ = id;
pool_ = pool;
}
}
public class DispatchStrategyFactory_impl extends org.omg.CORBA.LocalObject
implements DispatchStrategyFactory {
static final Logger logger = Logger.getLogger(DispatchStrategyFactory.class.getName());
//
// A sequence of thread pools. The index in the sequence is the
// thread pool id.
//
private java.util.Vector pools_ = new java.util.Vector();
//
// Has the default thread pool been created yet?
//
private boolean haveDefaultThreadPool_ = false;
//
// If so, what is the thread pool id?
//
private int defaultThreadPool_;
//
// Has the factory been destroyed?
//
private boolean destroy_ = false;
//
// The ORB instance
//
private ORBInstance orbInstance_ = null;
// ------------------------------------------------------------------
// Standard IDL to Java Mapping
// ------------------------------------------------------------------
public synchronized int create_thread_pool(int nthreads) {
//
// The ORB destroys this object, so it's an initialization
// error if this operation is called after ORB destruction
//
if (destroy_) {
throw new org.omg.CORBA.INITIALIZE(org.apache.yoko.orb.OB.MinorCodes
.describeInitialize(org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed),
org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
}
//
// Find the first empty thread pool
//
int i;
for (i = 0; i < pools_.size(); i++) {
if (pools_.elementAt(i) == null) {
break;
}
}
//
// If there is no empty slot then append an empty slot
//
if (i >= pools_.size()) {
pools_.addElement(null);
}
//
// Allocate a new ThreadPool
//
pools_.setElementAt(new ThreadPool(i, nthreads), i);
return i;
}
public synchronized void destroy_thread_pool(int id)
throws InvalidThreadPool {
//
// The ORB destroys this object, so it's an initialization error
// if this operation is called after ORB destruction
//
if (destroy_) {
throw new org.omg.CORBA.INITIALIZE(org.apache.yoko.orb.OB.MinorCodes
.describeInitialize(org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed),
org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
}
if (id < 0 || id > pools_.size() || pools_.elementAt(id) == null) {
throw new InvalidThreadPool();
}
//
// Destroy the ThreadPool
//
((ThreadPool) pools_.elementAt(id)).destroy();
//
// Empty the slot associated with this thread pool
//
pools_.setElementAt(null, id);
}
public synchronized DispatchStrategy create_thread_pool_strategy(int id)
throws InvalidThreadPool {
//
// The ORB destroys this object, so it's an initialization error
// if this operation is called after ORB destruction
//
if (destroy_) {
throw new org.omg.CORBA.INITIALIZE(org.apache.yoko.orb.OB.MinorCodes
.describeInitialize(org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed),
org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
}
if (id < 0 || id > pools_.size() || pools_.elementAt(id) == null) {
throw new InvalidThreadPool();
}
return new DispatchThreadPool_impl(id, (ThreadPool) pools_
.elementAt(id));
}
public synchronized DispatchStrategy create_same_thread_strategy() {
//
// The ORB destroys this object, so it's an initialization error
// if this operation is called after ORB destruction
//
if (destroy_) {
throw new org.omg.CORBA.INITIALIZE(org.apache.yoko.orb.OB.MinorCodes
.describeInitialize(org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed),
org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
}
return new DispatchSameThread_impl();
}
public synchronized DispatchStrategy create_thread_per_request_strategy() {
//
// The ORB destroys this object, so it's an initialization error
// if this operation is called after ORB destruction
//
if (destroy_) {
throw new org.omg.CORBA.INITIALIZE(org.apache.yoko.orb.OB.MinorCodes
.describeInitialize(org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed),
org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
}
return new DispatchThreadPerRequest_impl();
}
public synchronized DispatchStrategy create_default_dispatch_strategy() {
//
// The ORB destroys this object, so it's an initialization error
// if this operation is called after ORB destruction
//
if (destroy_) {
throw new org.omg.CORBA.INITIALIZE(org.apache.yoko.orb.OB.MinorCodes
.describeInitialize(org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed),
org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
}
//
// Get the ORB properties
//
java.util.Properties properties = orbInstance_.getProperties();
//
// Set the dispatch strategy policy as specified by the
// conc_model property
//
String value = properties.getProperty("yoko.orb.oa.conc_model");
if (value != null) {
logger.fine("Defined concurrency model is " + value);
if (value.equals("threaded") || value.equals("thread_per_client")) {
logger.fine("Using same thread dispatch strategy");
return create_same_thread_strategy();
} else if (value.equals("thread_per_request")) {
logger.fine("Using thread per request dispatch strategy");
return create_thread_per_request_strategy();
} else if (value.equals("thread_pool")) {
//
// If there is no default thread pool yet then create one,
// with a default of 10 threads.
//
if (!haveDefaultThreadPool_) {
haveDefaultThreadPool_ = true;
value = properties.getProperty("yoko.orb.oa.thread_pool");
int nthreads = 0;
if (value != null) {
nthreads = Integer.parseInt(value);
}
if (nthreads == 0) {
nthreads = 10;
}
logger.fine("Creating a thread pool of size " + nthreads);
defaultThreadPool_ = create_thread_pool(nthreads);
}
try {
logger.fine("Using a thread pool dispatch strategy");
return create_thread_pool_strategy(defaultThreadPool_);
} catch (InvalidThreadPool ex) {
Assert._OB_assert(ex);
}
} else {
String err = "yoko.orb.oa.conc_model: Unknown value `";
err += value;
err += "'";
orbInstance_.getLogger().warning(err);
}
}
//
// The default is to use a thread-per-request. Not doing this can cause
// deadlocks, so the single thread
//
logger.fine("Using default thread per request strategy");
return create_thread_per_request_strategy();
}
// ------------------------------------------------------------------
// Yoko internal functions
// Application programs must not use these functions directly
// ------------------------------------------------------------------
public DispatchStrategyFactory_impl() {
}
public synchronized void _OB_setORBInstance(ORBInstance orbInstance) {
orbInstance_ = orbInstance;
}
protected synchronized void _OB_destroy() {
//
// The ORB destroys this object, so it's an initialization error
// if this operation is called after ORB destruction
//
if (destroy_)
throw new org.omg.CORBA.INITIALIZE(org.apache.yoko.orb.OB.MinorCodes
.describeInitialize(org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed),
org.apache.yoko.orb.OB.MinorCodes.MinorORBDestroyed,
org.omg.CORBA.CompletionStatus.COMPLETED_NO);
destroy_ = true;
orbInstance_ = null;
//
// Destroy each of the thread pools
//
for (int i = 0; i < pools_.size(); i++) {
ThreadPool pool = (ThreadPool) pools_.elementAt(i);
if (pool != null) {
pool.destroy();
pools_.setElementAt(null, i);
}
}
}
}