This closes #2530
This commit is contained in:
commit
3de8b7bd96
|
@ -113,10 +113,12 @@ char* exceptionMessage(char* msg, int error) {
|
|||
error = error * -1;
|
||||
}
|
||||
//strerror is returning a constant, so no need to free anything coming from strerror
|
||||
char* err = strerror(error);
|
||||
char* result = malloc(strlen(msg) + strlen(err) + 1);
|
||||
strcpy(result, msg);
|
||||
strcat(result, err);
|
||||
char *result = NULL;
|
||||
|
||||
if (asprintf(&result, "%s%s", msg, strerror(error)) == -1) {
|
||||
fprintf(stderr, "Could not allocate enough memory for the error message: %s/%s\n", msg, strerror(error));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -358,72 +360,125 @@ JNIEXPORT jboolean JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContex
|
|||
return flock(handle, LOCK_EX | LOCK_NB) == 0;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroys the individual members of the IOCB pool
|
||||
* @param theControl the IO Control structure containing an IOCB pool
|
||||
* @param upperBound the number of elements contained within the pool
|
||||
*/
|
||||
static inline void iocb_destroy_members(struct io_control * theControl, int upperBound) {
|
||||
for (int i = 0; i < upperBound; i++) {
|
||||
free(theControl->iocb[i]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroys an IOCB pool and its members up to a certain limit. Should be used when the IOCB
|
||||
* pool fails to initialize completely
|
||||
* @param theControl the IO Control structure containing an IOCB pool
|
||||
* @param upperBound the number of elements contained within the pool
|
||||
*/
|
||||
static inline void iocb_destroy_bounded(struct io_control * theControl, int upperBound) {
|
||||
iocb_destroy_members(theControl, upperBound);
|
||||
free(theControl->iocb);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Destroys an IOCB pool and all its members
|
||||
* @param theControl
|
||||
*/
|
||||
static inline void iocb_destroy(struct io_control * theControl) {
|
||||
iocb_destroy_bounded(theControl, theControl->queueSize);
|
||||
}
|
||||
|
||||
/**
|
||||
* Everything that is allocated here will be freed at deleteContext when the class is unloaded.
|
||||
*/
|
||||
JNIEXPORT jobject JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_newContext(JNIEnv* env, jobject thisObject, jint queueSize) {
|
||||
io_context_t libaioContext;
|
||||
int i = 0;
|
||||
|
||||
#ifdef DEBUG
|
||||
fprintf (stdout, "Initializing context\n");
|
||||
#endif
|
||||
|
||||
int res = io_queue_init(queueSize, &libaioContext);
|
||||
if (res) {
|
||||
// Error, so need to release whatever was done before
|
||||
free(libaioContext);
|
||||
|
||||
throwRuntimeExceptionErrorNo(env, "Cannot initialize queue:", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct iocb ** iocb = (struct iocb **)malloc((sizeof(struct iocb *) * (size_t)queueSize));
|
||||
if (iocb == NULL) {
|
||||
throwOutOfMemoryError(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < queueSize; i++) {
|
||||
iocb[i] = (struct iocb *)malloc(sizeof(struct iocb));
|
||||
if (iocb[i] == NULL) {
|
||||
// it's unlikely this would happen at this point
|
||||
// for that reason I'm not cleaning up individual IOCBs here
|
||||
// we could increase support here with a cleanup of any previously allocated iocb
|
||||
// But I'm afraid of adding not needed complexity here
|
||||
throwOutOfMemoryError(env);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct io_control * theControl = (struct io_control *) malloc(sizeof(struct io_control));
|
||||
if (theControl == NULL) {
|
||||
throwOutOfMemoryError(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int res = io_queue_init(queueSize, &theControl->ioContext);
|
||||
if (res) {
|
||||
// Error, so need to release whatever was done before
|
||||
io_queue_release(theControl->ioContext);
|
||||
free(theControl);
|
||||
|
||||
throwRuntimeExceptionErrorNo(env, "Cannot initialize queue:", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
theControl->iocb = (struct iocb **)malloc((sizeof(struct iocb *) * (size_t)queueSize));
|
||||
if (theControl->iocb == NULL) {
|
||||
io_queue_release(theControl->ioContext);
|
||||
free(theControl);
|
||||
|
||||
throwOutOfMemoryError(env);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (i = 0; i < queueSize; i++) {
|
||||
theControl->iocb[i] = (struct iocb *)malloc(sizeof(struct iocb));
|
||||
if (theControl->iocb[i] == NULL) {
|
||||
|
||||
// It may not have been fully initialized, therefore limit the cleanup up to 'i' members.
|
||||
iocb_destroy_bounded(theControl, i);
|
||||
|
||||
io_queue_release(theControl->ioContext);
|
||||
free(theControl);
|
||||
|
||||
throwOutOfMemoryError(env);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
theControl->queueSize = queueSize;
|
||||
|
||||
|
||||
res = pthread_mutex_init(&(theControl->iocbLock), 0);
|
||||
if (res) {
|
||||
iocb_destroy(theControl);
|
||||
|
||||
io_queue_release(theControl->ioContext);
|
||||
free(theControl);
|
||||
free(libaioContext);
|
||||
|
||||
throwRuntimeExceptionErrorNo(env, "Can't initialize mutext:", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
res = pthread_mutex_init(&(theControl->pollLock), 0);
|
||||
if (res) {
|
||||
iocb_destroy(theControl);
|
||||
|
||||
io_queue_release(theControl->ioContext);
|
||||
free(theControl);
|
||||
free(libaioContext);
|
||||
|
||||
throwRuntimeExceptionErrorNo(env, "Can't initialize mutext:", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct io_event * events = (struct io_event *)malloc(sizeof(struct io_event) * (size_t)queueSize);
|
||||
theControl->events = (struct io_event *)malloc(sizeof(struct io_event) * (size_t)queueSize);
|
||||
if (theControl->events == NULL) {
|
||||
iocb_destroy(theControl);
|
||||
|
||||
io_queue_release(theControl->ioContext);
|
||||
free(theControl);
|
||||
|
||||
throwRuntimeExceptionErrorNo(env, "Can't initialize mutext (not enough memory for the events member): ", res);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
theControl->ioContext = libaioContext;
|
||||
theControl->events = events;
|
||||
theControl->iocb = iocb;
|
||||
theControl->queueSize = queueSize;
|
||||
theControl->iocbPut = 0;
|
||||
theControl->iocbGet = 0;
|
||||
theControl->used = 0;
|
||||
|
@ -470,14 +525,10 @@ JNIEXPORT void JNICALL Java_org_apache_activemq_artemis_jlibaio_LibaioContext_de
|
|||
pthread_mutex_destroy(&(theControl->pollLock));
|
||||
pthread_mutex_destroy(&(theControl->iocbLock));
|
||||
|
||||
// Releasing each individual iocb
|
||||
for (i = 0; i < theControl->queueSize; i++) {
|
||||
free(theControl->iocb[i]);
|
||||
}
|
||||
iocb_destroy(theControl);
|
||||
|
||||
(*env)->DeleteGlobalRef(env, theControl->thisObject);
|
||||
|
||||
free(theControl->iocb);
|
||||
free(theControl->events);
|
||||
free(theControl);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue