b5678a47a9
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
335 lines
11 KiB
C
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 ===============================*/
|