forked from tjfontaine/node-purple
-
Couldn't load subscription status.
- Fork 10
Crash less #8
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
tadzik
wants to merge
3
commits into
master
Choose a base branch
from
fix-me-maybe
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Crash less #8
Changes from all commits
Commits
Show all changes
3 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -28,6 +28,7 @@ typedef struct { | |
| } s_evLoopInput; | ||
|
|
||
| typedef struct { | ||
| guint id; | ||
| PurpleInputFunction func; | ||
| gpointer user_data; | ||
| int events; | ||
|
|
@@ -39,6 +40,9 @@ typedef struct { | |
| uv_loop_t* loop; | ||
| // fd -> s_evLoopInput | ||
| GHashTable* inputs; | ||
| guint last_event_id; | ||
| // guint -> s_evLoopInputEvent | ||
| GHashTable* events; | ||
| } s_evLoopState; | ||
|
|
||
| void call_callback(uv_timer_t* handle); | ||
|
|
@@ -98,7 +102,7 @@ guint timeout_add_seconds(guint interval, GSourceFunc function, gpointer data) { | |
| return timeout_add(interval*1000, function, data); | ||
| } | ||
|
|
||
| void on_timer_close_complete(uv_handle_t* handle) | ||
| void on_handle_close_complete(uv_handle_t* handle) | ||
| { | ||
| free(handle->data); | ||
| free(handle); | ||
|
|
@@ -119,7 +123,7 @@ gboolean timeout_remove(guint int_handle) { | |
| s_evLoopTimer *timer = handle; | ||
| uv_timer_stop(timer->handle); | ||
| if (!uv_is_closing((uv_handle_t*)timer->handle)) { | ||
| uv_close((uv_handle_t*)timer->handle, on_timer_close_complete); | ||
| uv_close((uv_handle_t*)timer->handle, on_handle_close_complete); | ||
| } | ||
| return true; | ||
| } | ||
|
|
@@ -139,7 +143,6 @@ void handle_input(uv_poll_t* handle, int status, int events) { | |
| // Unexpected positive status | ||
| g_warning("handle_input unexpected positive status %i\n", status); | ||
| } | ||
| int closedFD = -1; | ||
| s_evLoopInput *input = handle->data; | ||
| GList *elem; | ||
| s_evLoopInputEvent *inputEvent; | ||
|
|
@@ -186,7 +189,7 @@ guint input_add(int fd, PurpleInputCondition cond, | |
| input_event->func = func; | ||
| input_event->user_data = user_data; | ||
|
|
||
| s_evLoopInput *input_handle = g_hash_table_lookup(evLoopState.inputs, &fd); | ||
| s_evLoopInput *input_handle = g_hash_table_lookup(evLoopState.inputs, GINT_TO_POINTER(fd)); | ||
| if (input_handle == NULL) { | ||
| input_handle = g_malloc(sizeof(s_evLoopInput)); | ||
| input_handle->fd = fd; | ||
|
|
@@ -195,16 +198,20 @@ guint input_add(int fd, PurpleInputCondition cond, | |
| input_handle->events = NULL; | ||
| uv_handle_set_data((uv_handle_t*)input_handle->handle, input_handle); | ||
| uv_poll_init(evLoopState.loop, input_handle->handle, fd); | ||
| g_hash_table_insert(evLoopState.inputs, &input_handle->fd, input_handle); | ||
| g_hash_table_insert(evLoopState.inputs, GINT_TO_POINTER(fd), input_handle); | ||
| } else { | ||
| // Nothing to do, except update the condition on the poll | ||
| input_handle->cond |= cond; | ||
| } | ||
| // This will update the handle if the cond changed. | ||
| uv_poll_start(input_handle->handle, input_handle->cond, handle_input); | ||
| input_event->parent = input_handle; | ||
| input_handle->events = g_list_append(input_handle->events, input_event); | ||
| return GPOINTER_TO_UINT(input_event); | ||
|
|
||
| input_event->id = evLoopState.last_event_id++; | ||
| g_hash_table_insert(evLoopState.events, GUINT_TO_POINTER(input_event->id), input_event); | ||
|
|
||
| uv_poll_start(input_handle->handle, input_handle->cond, handle_input); | ||
| return input_event->id; | ||
| } | ||
|
|
||
| /** | ||
|
|
@@ -213,26 +220,24 @@ guint input_add(int fd, PurpleInputCondition cond, | |
| * @return @c TRUE if the input handler was found and removed. | ||
| * @see purple_input_remove | ||
| */ | ||
| gboolean input_remove (guint int_handle) { | ||
| gpointer handle = GUINT_TO_POINTER(int_handle); | ||
| g_return_val_if_fail(handle != NULL, false); | ||
| s_evLoopInputEvent *inputEvent = handle; | ||
| gboolean input_remove (guint input_event_id) { | ||
| s_evLoopInputEvent *inputEvent = g_hash_table_lookup(evLoopState.events, GUINT_TO_POINTER(input_event_id)); | ||
| g_return_val_if_fail(inputEvent != NULL, false); | ||
| s_evLoopInput *input = inputEvent->parent; | ||
| // Why is this here? XXX | ||
| if (g_list_find(input->events, inputEvent) == NULL) { | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this is used to check if the input actually exists in our hash, but granted it's probably pointless here. |
||
| return false; | ||
| } | ||
| input->events = g_list_remove(input->events, inputEvent); | ||
| free(inputEvent); | ||
| g_free(inputEvent); | ||
| guint listeners = g_list_length(input->events); | ||
| if (listeners > 0) { | ||
| // TODO: We should change the flags for the poll handle here. | ||
| return true; | ||
| // Do not clean up the handle yet. | ||
| } | ||
| uv_poll_stop(input->handle); | ||
| g_hash_table_remove(evLoopState.inputs, &input->fd); | ||
| free(input->handle); | ||
| free(input); | ||
| uv_close((uv_handle_t*)input->handle, on_handle_close_complete); | ||
| g_hash_table_remove(evLoopState.inputs, GINT_TO_POINTER(input->fd)); | ||
| return true; | ||
| } | ||
|
|
||
|
|
@@ -256,7 +261,8 @@ PurpleEventLoopUiOps* eventLoop_get(napi_env* env) { | |
| if (napi_get_uv_event_loop(*env, &evLoopState.loop) != napi_ok) { | ||
| THROW(*env, NULL, "Could not get UV loop", NULL); | ||
| } | ||
| evLoopState.inputs = g_hash_table_new_full(g_int_hash, g_int_equal, NULL, NULL); | ||
| evLoopState.inputs = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); | ||
| evLoopState.events = g_hash_table_new_full(g_direct_hash, g_direct_equal, NULL, NULL); | ||
| } | ||
| return &glib_eventloops; | ||
| } | ||
|
|
@@ -271,7 +277,7 @@ void call_callback(uv_timer_t* handle) { | |
| gboolean res = timer->function(timer->data); | ||
| // If the function succeeds, continue | ||
| if (!res && !uv_is_closing((uv_handle_t *)timer->handle)) { | ||
| uv_close((uv_handle_t *)timer->handle, on_timer_close_complete); | ||
| uv_close((uv_handle_t *)timer->handle, on_handle_close_complete); | ||
| return; | ||
| } | ||
| uv_timer_again(handle); | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should probably check if we didn't overflow here – how knows for how many decades it can run now that it got as stable as it is ;)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we can check if
evLoopState.last_event_idis maxint if you like, but honestly...meeeh