storlets/src/java/SBus/SBusJNI.c
Takashi Kajinami b5678a47a9 Stop Inactive storlet processes automatically
This patch implements timeout on sbus.listen method, and makes
storlet daemon factories and storlet daemons which are not active
for long time automatically terminate.

Closes-bug: #1615927
Change-Id: Ic3e502995f1a125d449fcb88613290c65183face
2021-08-19 09:17:26 +00:00

335 lines
11 KiB
C

/*----------------------------------------------------------------------------
* Copyright IBM Corp. 2015, 2015 All Rights Reserved
* Copyright (c) 2010-2016 OpenStack Foundation
* Licensed 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.
* ---------------------------------------------------------------------------
*/
#include <jni.h>
#include <stdlib.h>
#include <stdio.h>
#include <syslog.h>
#include <string.h>
#include "org_openstack_storlet_sbus_SBusJNI.h"
#include "sbus.h"
static int g_JavaAccessorsInitialized = 0;
static jclass g_ClassRawMessage = NULL;
static jmethodID g_RawMessageCTOR = NULL;
static jfieldID g_FieldFDs = NULL;
static jfieldID g_FieldMetadata = NULL;
static jfieldID g_FieldParams = NULL;
static jclass g_ClassFileDescriptor = NULL;
static jmethodID g_FDCTOR = NULL;
static jfieldID g_FieldRawFD = NULL;
/*----------------------------------------------------------------------------
* init_java_accessors
*
* Preparing access to some Java-land objects
* */
int init_java_accessors( JNIEnv* env )
{
// TODO: Fix to read only once.
// Currently seem to fail
//if( 1 == g_JavaAccessorsInitialized )
// return 0;
/*------------------------------------------------------------------------
* Reflecting SBusRawMessage
* */
g_ClassRawMessage =
(*env)->FindClass( env, "org/openstack/storlet/sbus/SBusRawMessage" );
if( NULL == g_ClassRawMessage )
return -1;
g_RawMessageCTOR =
(*env)->GetMethodID(env, g_ClassRawMessage, "<init>", "()V");
if( NULL == g_RawMessageCTOR )
return -1;
g_FieldFDs =
(*env)->GetFieldID( env, g_ClassRawMessage,
"hFiles_", "[Ljava/io/FileDescriptor;");
if( NULL == g_FieldFDs )
return -1;
g_FieldParams =
(*env)->GetFieldID( env, g_ClassRawMessage,
"strParams_", "Ljava/lang/String;");
if( NULL == g_FieldParams )
return -1;
g_FieldMetadata =
(*env)->GetFieldID( env, g_ClassRawMessage,
"strMetadata_", "Ljava/lang/String;");
if( NULL == g_FieldMetadata )
return -1;
/*------------------------------------------------------------------------
* Reflecting java.io.FileDescriptor
* */
g_ClassFileDescriptor =
(*env)->FindClass(env, "java/io/FileDescriptor");
if( NULL == g_ClassFileDescriptor )
return -1;
g_FDCTOR =
(*env)->GetMethodID(env, g_ClassFileDescriptor, "<init>", "()V");
if( NULL == g_FDCTOR )
return -1;
g_FieldRawFD =
(*env)->GetFieldID(env, g_ClassFileDescriptor, "fd", "I");
if( NULL == g_FieldRawFD )
return -1;
// Initialization succeeded. Flag up.
g_JavaAccessorsInitialized = 1;
return 0;
}
/*----------------------------------------------------------------------------
*
* */
JNIEXPORT void JNICALL
Java_org_openstack_storlet_sbus_SBusJNI_startLogger( JNIEnv* env,
jobject obj,
jstring jLevel,
jstring jContId )
{
const char* pLogLevel = (*env)->GetStringUTFChars( env, jLevel, NULL );
if( NULL == pLogLevel )
return;
const char* pContId = (*env)->GetStringUTFChars( env, jContId, NULL );
if( NULL == pContId )
return;
sbus_start_logger( pLogLevel, pContId);
(*env)->ReleaseStringUTFChars( env, jLevel, pLogLevel );
}
/*----------------------------------------------------------------------------
*
* */
JNIEXPORT void JNICALL
Java_org_openstack_storlet_sbus_SBusJNI_stopLogger( JNIEnv* env,
jobject obj )
{
sbus_stop_logger();
}
/*----------------------------------------------------------------------------
*
* */
JNIEXPORT jint JNICALL
Java_org_openstack_storlet_sbus_SBusJNI_createSBus( JNIEnv* env,
jobject obj,
jstring jstrPath )
{
int nBus = -1;
const char* pPath = (*env)->GetStringUTFChars( env, jstrPath, NULL );
if( NULL == pPath )
return -1;
nBus = sbus_create( pPath);
(*env)->ReleaseStringUTFChars( env, jstrPath, pPath );
return nBus;
}
/*----------------------------------------------------------------------------
*
* */
JNIEXPORT jint JNICALL
Java_org_openstack_storlet_sbus_SBusJNI_listenSBus( JNIEnv* env,
jobject obj,
jint jnBus,
jfloat jfTimeout )
{
return sbus_listen( jnBus , jfTimeout );
}
/*----------------------------------------------------------------------------
*
* */
JNIEXPORT jint JNICALL
Java_org_openstack_storlet_sbus_SBusJNI_sendRawMessage( JNIEnv* env,
jobject obj,
jstring jstrPath,
jobject jMsg )
{
syslog( LOG_DEBUG, "Inside sendRawMessage" );
if( init_java_accessors( env ) )
return -1;
int i,j;
int nStatus = 0;
const char* strSBusPath = 0;
const char* strMetadata = 0;
int nMetadataLen = 0;
const char* strParams = 0;
int nParamsLen = 0;
int* pFiles = 0;
int nFiles = 0;
strSBusPath = (*env)->GetStringUTFChars( env, jstrPath, NULL );
if( NULL == strSBusPath )
return -1;
jobjectArray jFileDscrArr =
(jobjectArray)(*env)->GetObjectField(env, jMsg, g_FieldFDs );
if( NULL != jFileDscrArr )
{
nFiles = (*env)->GetArrayLength(env, jFileDscrArr );
pFiles = (int*) malloc( nFiles * sizeof(int) );
for( i = 0; i < nFiles; ++i )
{
jobject jFileDscr =
(*env)->GetObjectArrayElement( env, jFileDscrArr, i );
pFiles[i] = (*env)->GetIntField( env, jFileDscr, g_FieldRawFD );
}
}
jstring jstrMetadata =
(jstring)(*env)->GetObjectField(env, jMsg, g_FieldMetadata );
if( NULL != jstrMetadata )
{
strMetadata = (*env)->GetStringUTFChars( env, jstrMetadata, NULL );
nMetadataLen = strlen( strMetadata );
}
jstring jstrParams =
(jstring)(*env)->GetObjectField(env, jMsg, g_FieldParams );
if( NULL != jstrParams )
{
strParams = (*env)->GetStringUTFChars( env, jstrParams, NULL );
nParamsLen = strlen( strParams );
}
nStatus = sbus_send_msg( strSBusPath,
pFiles, nFiles,
strMetadata, nMetadataLen,
strParams, nParamsLen );
if( NULL != jstrMetadata )
(*env)->ReleaseStringUTFChars( env, jstrMetadata, strMetadata );
if( NULL != jstrParams )
(*env)->ReleaseStringUTFChars( env, jstrParams, strParams );
if( NULL != jFileDscrArr )
free( pFiles );
return nStatus;
}
/*----------------------------------------------------------------------------
*
* */
JNIEXPORT jobject JNICALL
Java_org_openstack_storlet_sbus_SBusJNI_receiveRawMessage( JNIEnv* env,
jobject obj,
jint jnBus )
{
syslog( LOG_DEBUG, "JNI: Inside receiveRawMessage" );
if( init_java_accessors( env ) )
return NULL;
int i,j;
int nStatus = 0;
jobject RawMsgObj = 0;
char* strMetadata = 0;
int nMetadataLen = 0;
char* strParams = 0;
int nParamsLen = 0;
int* pFiles = 0;
int nFiles = 0;
nStatus = sbus_recv_msg( jnBus,
&pFiles, &nFiles,
&strMetadata, &nMetadataLen,
&strParams, &nParamsLen );
syslog( LOG_DEBUG, "JNI: sbus_recv_msg = %d, "
"nFiles = %d, "
"nMetadataLen = %d, "
"nParamsLen = %d",
nStatus, nFiles, nMetadataLen, nParamsLen );
if( 0 <= nStatus )
{
strParams[nParamsLen] = '\0';
// Create result object
RawMsgObj = (*env)->NewObject( env,
g_ClassRawMessage,
g_RawMessageCTOR );
// Params is never empty. We have 'command' at least.
jstring jstrParams = (*env)->NewStringUTF( env, strParams );
(*env)->SetObjectField( env, RawMsgObj, g_FieldParams, jstrParams );
if( 0 < nFiles )
{
strMetadata[nMetadataLen] = '\0';
// Instantiate FileDescriptor array
jobjectArray jFileDscrArr =
(*env)->NewObjectArray( env, nFiles,
g_ClassFileDescriptor,
NULL );
jobject jFileDscr;
for( i = 0; i < nFiles; ++i )
{
jFileDscr = (*env)->NewObject( env,
g_ClassFileDescriptor,
g_FDCTOR );
(*env)->SetIntField( env,
jFileDscr,
g_FieldRawFD,
pFiles[i] );
(*env)->SetObjectArrayElement( env,
jFileDscrArr,
i,
jFileDscr );
}
// Assign obtained object
(*env)->SetObjectField(env,RawMsgObj, g_FieldFDs, jFileDscrArr );
jstring jstrMetadata = (*env)->NewStringUTF(env, strMetadata );
(*env)->SetObjectField( env,
RawMsgObj,
g_FieldMetadata,
jstrMetadata );
}
syslog(LOG_DEBUG, "receiveRawMessage: %d files", nFiles );
}
// Clean up
free( pFiles );
free( strMetadata );
free( strParams );
return RawMsgObj;
}
/*============================== END OF FILE ===============================*/