Drive all levels through UI instrumentation
This commit is contained in:
@@ -21,11 +21,6 @@ struct output_buffer {
|
||||
size_t capacity;
|
||||
};
|
||||
|
||||
struct reader_state {
|
||||
int fd;
|
||||
struct output_buffer output;
|
||||
};
|
||||
|
||||
static pthread_mutex_t git_mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
static void *git_handle = NULL;
|
||||
static git_main_fn git_main = NULL;
|
||||
@@ -54,23 +49,28 @@ static int append_output(struct output_buffer *buffer, const char *data, size_t
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void *read_output(void *arg) {
|
||||
struct reader_state *state = (struct reader_state *)arg;
|
||||
static int drain_available_output(int fd, struct output_buffer *output, int *saw_eof) {
|
||||
char chunk[4096];
|
||||
for (;;) {
|
||||
ssize_t count = read(state->fd, chunk, sizeof(chunk));
|
||||
ssize_t count = read(fd, chunk, sizeof(chunk));
|
||||
if (count > 0) {
|
||||
if (append_output(&state->output, chunk, (size_t)count) != 0) {
|
||||
break;
|
||||
if (append_output(output, chunk, (size_t)count) != 0) {
|
||||
return -1;
|
||||
}
|
||||
} else if (count == 0) {
|
||||
break;
|
||||
} else if (errno != EINTR) {
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (count == 0) {
|
||||
*saw_eof = 1;
|
||||
return 0;
|
||||
}
|
||||
if (errno == EINTR) {
|
||||
continue;
|
||||
}
|
||||
if (errno == EAGAIN || errno == EWOULDBLOCK) {
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
close(state->fd);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static jobjectArray make_result(JNIEnv *env, int exit_code, const char *output) {
|
||||
@@ -267,12 +267,36 @@ Java_solutions_tretter_githugandroid_NativeGitBridge_runGitMainNative(
|
||||
}
|
||||
|
||||
close(pipe_fds[1]);
|
||||
struct reader_state reader = { .fd = pipe_fds[0], .output = {0} };
|
||||
read_output(&reader);
|
||||
struct output_buffer output = {0};
|
||||
int flags = fcntl(pipe_fds[0], F_GETFL, 0);
|
||||
if (flags >= 0) {
|
||||
fcntl(pipe_fds[0], F_SETFL, flags | O_NONBLOCK);
|
||||
}
|
||||
|
||||
int child_status = 0;
|
||||
while (waitpid(child, &child_status, 0) < 0 && errno == EINTR) {
|
||||
int child_done = 0;
|
||||
int saw_eof = 0;
|
||||
while (!child_done || !saw_eof) {
|
||||
if (drain_available_output(pipe_fds[0], &output, &saw_eof) != 0) {
|
||||
break;
|
||||
}
|
||||
if (!child_done) {
|
||||
pid_t wait_result = waitpid(child, &child_status, WNOHANG);
|
||||
if (wait_result == child) {
|
||||
child_done = 1;
|
||||
} else if (wait_result < 0 && errno != EINTR) {
|
||||
child_done = 1;
|
||||
}
|
||||
}
|
||||
if (child_done) {
|
||||
if (!saw_eof) {
|
||||
drain_available_output(pipe_fds[0], &output, &saw_eof);
|
||||
}
|
||||
break;
|
||||
}
|
||||
usleep(10000);
|
||||
}
|
||||
close(pipe_fds[0]);
|
||||
pthread_mutex_unlock(&git_mutex);
|
||||
|
||||
int exit_code = -1;
|
||||
@@ -282,9 +306,9 @@ Java_solutions_tretter_githugandroid_NativeGitBridge_runGitMainNative(
|
||||
exit_code = 128 + WTERMSIG(child_status);
|
||||
}
|
||||
|
||||
jobjectArray result = make_result(env, exit_code, reader.output.data);
|
||||
jobjectArray result = make_result(env, exit_code, output.data);
|
||||
|
||||
free(reader.output.data);
|
||||
free(output.data);
|
||||
free_string_array(argv, argc);
|
||||
free_string_array(env_entries, envc);
|
||||
(*env)->ReleaseStringUTFChars(env, library_path, library_path_chars);
|
||||
|
||||
Reference in New Issue
Block a user