blob: 66e32ed6bb5f1cbbfa299296ed1cf87f9c2333ac [file] [log] [blame]
/**********************************************************************
// @@@ START COPYRIGHT @@@
//
// 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.
//
// @@@ END COPYRIGHT @@@
**********************************************************************/
#ifndef __EX_UDR_SERVER_H
#define __EX_UDR_SERVER_H
/* -*-C++-*-
*****************************************************************************
*
* File: ExUdrServer.h
* Description: Client-side process management for UDR servers
*
* Created: 08/16/2000
* Language: C++
*
*
*****************************************************************************
*/
#include "ComSmallDefs.h"
#include "UdrExeIpc.h"
#include "ExCollections.h"
#include "NAUserId.h"
// Default nowait depth of 3 is used for connections (except control
// connection) to UDR Server
#define DEFAULT_NOWAIT_DEPTH 3
// -----------------------------------------------------------------------
// Forward class references
// -----------------------------------------------------------------------
class UdrControlMsg;
class UdrClientControlStream;
class ExUdrTcb;
class IpcProcessId;
// -----------------------------------------------------------------------
// Classes defined in this file
// -----------------------------------------------------------------------
class ExUdrServer;
class ExUdrServerManager;
extern NABoolean ProcessIdIsNull(const IpcProcessId &);
extern void InvalidateProcessId(IpcProcessId &);
// -----------------------------------------------------------------------
// ExUdrServer
// -----------------------------------------------------------------------
class ExUdrServer : public NABasicObject
{
public:
enum ExUdrServerStatus
{
EX_UDR_SUCCESS = 0,
EX_UDR_WARNING,
EX_UDR_ERROR
};
enum ExUdrServerState
{
EX_UDR_NOT_STARTED = 0,
EX_UDR_READY,
EX_UDR_BROKEN
};
ExUdrServer(IpcEnvironment *env,
const Int32 &userId,
const char *options,
const char *optionDelimiters,
const char *userName,
const char *userPassword,
IpcServerClass *serverClass);
~ExUdrServer();
void setState(ExUdrServerState state) { state_ = state; }
ExUdrServerState getState() const { return state_; }
void setDedicated(NABoolean dedicated) { dedicated_ = dedicated; }
NABoolean isDedicated(void) { return dedicated_;}
void setInUse(NABoolean inUse) { inUse_ = inUse; }
NABoolean inUse(void){ return inUse_;}
ExUdrServerStatus start(ComDiagsArea **diags,
CollHeap *diagsHeap,
Int64 transId,
IpcProcessId &newId,
NABoolean usesTransactions);
ExUdrServerStatus stop();
ExUdrServerStatus kill(ComDiagsArea *diags);
const IpcProcessId getServerProcessId() const { return serverProcessId_; }
const char *getOptions() const { return options_; }
const char *getOptionDelimiters() const { return optionDelimiters_; }
// Helper function to send down server-side runtime options. Must be
// called only after successful startup of the server.
void sendStartupOptions(ComDiagsArea **diags, CollHeap *diagsHeap,
Int64 transId);
// Matchmaking logic to determine if this server has the requested
// attributes
NABoolean match(const Int32 &userId,
const char *options,
const char *optionDelimiters) const;
//
// Functions to quiesce the UDR server
// - isIOPending() returns TRUE if any replies are outstanding.
// - completeUdrRequests(TRUE) polls for I/O completion until
// isIOPending() returns FALSE. completeUdrRequests(FALSE)
// waits for one I/O to complete then returns.
//
NABoolean isIOPending(IpcConnection *conn) const;
void completeUdrRequests(IpcConnection *conn, NABoolean waitForAllIO) const;
IpcConnection *getUdrControlConnection() const;
IpcConnection *getAnIpcConnection() const;
void releaseConnection(IpcConnection *conn);
IpcEnvironment *myIpcEnv() const { return ipcEnvironment_; }
CollHeap *myIpcHeap() const;
void incrRefCount() { ++refCount_; }
void decrRefCount() { --refCount_; }
void setRefCount(ComUInt32 refCount) { refCount_ = refCount; }
ComUInt32 getRefCount() const { return refCount_; }
const Int32 &getUserId() const { return userId_; };
#ifdef UDR_DEBUG
void setTraceFile(FILE *f)
{
traceFile_ = f;
}
#endif
protected:
inline NABoolean ready() const { return (state_ == EX_UDR_READY); }
ExUdrServerState state_;
IpcEnvironment *ipcEnvironment_;
IpcServerClass *udrServerClass_;
IpcServer *ipcServer_;
IpcProcessId serverProcessId_;
ULng32 startAttempts_;
// The user identity for this UDR server
Int32 userId_;
char *userName_;
char *userPassword_;
// Server-side runtime options. Currently the options_ string stores
// JVM startup options only.
char *options_;
char *optionDelimiters_;
// A small summary of how reference count, dedicated and inUse flags
// are used. Note that there are three layers of maintaining the
// usage of mxudr servers. First layer being the top layer.
// First layer: Server Manager is an instance in CliGlobals. Server
// manager either creates a new server process or returns a existing
// server in its pool for reuse. Server manager maintains a single
// list of servers.
//
// Second layer: ContextCli obtains servers from server manager or
// the first layer on a need basis. ContextCli reuses servers in its
// pool to service requests from various statements in its scope.
// contextCli can request a shared or a dedicated server from server
// manager. A dedicated server request to server manager will always
// return a server whose reference count is 1.
// Note that server manager upon request from other contextCli requests for
// a shared mode server will not hand over a server from its pool that has
// been already obtained as dedicated by another contextCli.
// Referece count of server is always incremented by one (by the server
// manager) when ContextCli obtaines a server from server manager. Once
// the server is in ContextCli scope, its reference count is not altered
// in contextCli scope. Reference count is decremented once contectCli
// returns the server back to server manager. Once the server is returned
// back to server manager, it is free to be reassined to other contextCli
// requests as a shared or dedicated server.
// ContextCli uses the list of servers to complete Io or return back servers
// when under certain scenarios. search for udrServerList_ in contextCli scope.
// Third layer: ex_exe_statement_globals obtains servers from contextcli on
// a demand basis. Multiple tcbs in a statment may use a server that is obtained
// from contextcli in shared mode. For TMUDF tcbs, a dedicated server from
// contextCli would be obtained in dedicated mode. ex_exe_statement_globals
// maintains a single pointer to server that is obtained in shared mode and
// a separate list of pointers to servers that have been obtained in dedicated mode.
// Ex_exe_statement_global sets the inUse_ flag for dedicated servers so that
// contextCli does not hand the same dedicated server to other statements.
// Number of contexts and TCBs using this ExUdrServer object. A
// refCount of 0 means no other objects are using this UDR server
// and it can be returned to the pool of idle servers, or released.
ComUInt32 refCount_;
// This flag indicates that the server is obtained as dedicated and
// cannot be shared with other contextCli requests. Usually this flag
// is set dedicated by contextCli attempting to get this server in dedicated
// mode, usuually to service a TMUDF client. A dedicated server is
// usually used by one client and never shared until it is not in use.
// see inUse_ flag.
NABoolean dedicated_;
// Ex_exe_statement_global sets the inUse_ flag for dedicated servers so that
// contextCli does not hand the same dedicated server to other statements.
// inUse_ flag is reset once a statement is deallocated.
NABoolean inUse_;
// Lists to maintain IPC Connections to the UDR Server process
NAList<IpcConnection *> *inUseConns_;
NAList<IpcConnection *> *freeConns_;
#ifdef UDR_DEBUG
FILE *traceFile_;
#endif
private:
ExUdrServer(); // do not implement a default constructor
};
// -----------------------------------------------------------------------
// ExUdrServerManager
// -----------------------------------------------------------------------
class ExUdrServerManager : public NABasicObject
{
public:
ExUdrServerManager(
IpcEnvironment *env,
ComUInt32 maxServersPerGroup = 1);
~ExUdrServerManager();
// This method provides access to a UDR server with the requested
// attributes. Successful completion of this method does not
// guarantee that the process is actually started. Currently the
// options parameter is for JVM startup options only, and simple
// string comparision is our test to determine if two option sets
// are equivalent.
ExUdrServer *acquireUdrServer(const Int32 &userId,
const char *options,
const char *optionDelimiters,
const char *userName,
const char *userPassword,
NABoolean dedicated = FALSE);
// Decrement the reference count for a given ExUdrServer instance
void releaseUdrServer(ExUdrServer *udrServer);
// This is the heap that will be used for all dynamic memory
// allocations
inline CollHeap *myIpcHeap() const
{
return ipcEnvironment_->getHeap();
}
inline ComUInt32 getMaxServersPerGroup() const
{ return maxServersPerGroup_; }
protected:
// We need an IpcEnvironment pointer to create ExUdrServer objects.
// That's why we store this here. All ExUdrServer objects share
// this pointer.
IpcEnvironment *ipcEnvironment_;
// Server class used to create a server process. This pointer will
// be copied to all ExUdrServer objects.
IpcServerClass *udrServerClass_;
// Pool of ExUdrServers
LIST(ExUdrServer*) serverPool_;
// Maximum number of servers an executor can create with a given set
// of attributes. Currently this value is set to 1. In the future if
// we want to manage multiple servers with the same attributes we
// can set this value higher.
ComUInt32 maxServersPerGroup_;
// The following boolean helps us decide when it is OK to retain an
// unused server in the pool for an application that only requires a
// single server.
NABoolean okToRetainOneServer_;
#ifdef UDR_DEBUG
FILE *traceFile_;
#endif
};
#endif // __EX_UDR_SERVER_H