mirror of
https://github.com/rkd77/elinks.git
synced 2024-12-04 14:46:47 -05:00
Merge branch 'elinks-0.12' into elinks-0.13
This commit is contained in:
commit
9c17d8e805
@ -118,13 +118,19 @@ get_connections_transfering_count(void)
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Check whether the pointer @a conn still points to a connection
|
||||||
|
* with the given @a id. If the struct connection has already been
|
||||||
|
* freed, this returns 0. By comparing connection.id, this function
|
||||||
|
* can usually detect even the case where a different connection has
|
||||||
|
* been created at the same address. For that to work, the caller
|
||||||
|
* must save the connection.id before the connection can be deleted. */
|
||||||
static inline int
|
static inline int
|
||||||
connection_disappeared(struct connection *conn)
|
connection_disappeared(struct connection *conn, unsigned int id)
|
||||||
{
|
{
|
||||||
struct connection *c;
|
struct connection *c;
|
||||||
|
|
||||||
foreach (c, connection_queue)
|
foreach (c, connection_queue)
|
||||||
if (conn == c && conn->id == c->id)
|
if (conn == c && id == c->id)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
@ -361,17 +367,19 @@ set_connection_state(struct connection *conn, struct connection_state state)
|
|||||||
|
|
||||||
conn->state = state;
|
conn->state = state;
|
||||||
if (is_in_state(conn->state, S_TRANS)) {
|
if (is_in_state(conn->state, S_TRANS)) {
|
||||||
|
const unsigned int id = conn->id;
|
||||||
|
|
||||||
if (upload_progress && upload_progress->timer == TIMER_ID_UNDEF) {
|
if (upload_progress && upload_progress->timer == TIMER_ID_UNDEF) {
|
||||||
start_update_progress(upload_progress,
|
start_update_progress(upload_progress,
|
||||||
(void (*)(void *)) upload_stat_timer, conn);
|
(void (*)(void *)) upload_stat_timer, conn);
|
||||||
upload_stat_timer(conn);
|
upload_stat_timer(conn);
|
||||||
if (connection_disappeared(conn))
|
if (connection_disappeared(conn, id))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (progress->timer == TIMER_ID_UNDEF) {
|
if (progress->timer == TIMER_ID_UNDEF) {
|
||||||
start_update_progress(progress, (void (*)(void *)) stat_timer, conn);
|
start_update_progress(progress, (void (*)(void *)) stat_timer, conn);
|
||||||
update_connection_progress(conn);
|
update_connection_progress(conn);
|
||||||
if (connection_disappeared(conn))
|
if (connection_disappeared(conn, id))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,13 +458,15 @@ static void
|
|||||||
notify_connection_callbacks(struct connection *conn)
|
notify_connection_callbacks(struct connection *conn)
|
||||||
{
|
{
|
||||||
struct connection_state state = conn->state;
|
struct connection_state state = conn->state;
|
||||||
|
unsigned int id = conn->id;
|
||||||
struct download *download, *next;
|
struct download *download, *next;
|
||||||
|
|
||||||
foreachsafe (download, next, conn->downloads) {
|
foreachsafe (download, next, conn->downloads) {
|
||||||
download->cached = conn->cached;
|
download->cached = conn->cached;
|
||||||
if (download->callback)
|
if (download->callback)
|
||||||
download->callback(download, download->data);
|
download->callback(download, download->data);
|
||||||
if (is_in_progress_state(state) && connection_disappeared(conn))
|
if (is_in_progress_state(state)
|
||||||
|
&& connection_disappeared(conn, id))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -69,6 +69,16 @@ struct connect_info {
|
|||||||
struct uri *uri; /* For updating the blacklist. */
|
struct uri *uri; /* For updating the blacklist. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** For detecting whether a struct socket has been deleted while a
|
||||||
|
* function was using it. */
|
||||||
|
struct socket_weak_ref {
|
||||||
|
LIST_HEAD(struct socket_weak_ref);
|
||||||
|
|
||||||
|
/** done_socket() resets this to NULL. */
|
||||||
|
struct socket *socket;
|
||||||
|
};
|
||||||
|
|
||||||
|
static INIT_LIST_OF(struct socket_weak_ref, socket_weak_refs);
|
||||||
|
|
||||||
/* To enable logging of tranfers, for debugging purposes. */
|
/* To enable logging of tranfers, for debugging purposes. */
|
||||||
#if 0
|
#if 0
|
||||||
@ -143,6 +153,8 @@ init_socket(void *conn, struct socket_operations *ops)
|
|||||||
void
|
void
|
||||||
done_socket(struct socket *socket)
|
done_socket(struct socket *socket)
|
||||||
{
|
{
|
||||||
|
struct socket_weak_ref *ref;
|
||||||
|
|
||||||
close_socket(socket);
|
close_socket(socket);
|
||||||
|
|
||||||
if (socket->connect_info)
|
if (socket->connect_info)
|
||||||
@ -150,6 +162,11 @@ done_socket(struct socket *socket)
|
|||||||
|
|
||||||
mem_free_set(&socket->read_buffer, NULL);
|
mem_free_set(&socket->read_buffer, NULL);
|
||||||
mem_free_set(&socket->write_buffer, NULL);
|
mem_free_set(&socket->write_buffer, NULL);
|
||||||
|
|
||||||
|
foreach(ref, socket_weak_refs) {
|
||||||
|
if (ref->socket == socket)
|
||||||
|
ref->socket = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -935,13 +952,26 @@ void
|
|||||||
read_from_socket(struct socket *socket, struct read_buffer *buffer,
|
read_from_socket(struct socket *socket, struct read_buffer *buffer,
|
||||||
struct connection_state state, socket_read_T done)
|
struct connection_state state, socket_read_T done)
|
||||||
{
|
{
|
||||||
|
const int is_buffer_new = (buffer != socket->read_buffer);
|
||||||
|
struct socket_weak_ref ref;
|
||||||
select_handler_T write_handler;
|
select_handler_T write_handler;
|
||||||
|
|
||||||
|
ref.socket = socket;
|
||||||
|
add_to_list(socket_weak_refs, &ref);
|
||||||
|
|
||||||
buffer->done = done;
|
buffer->done = done;
|
||||||
|
|
||||||
socket->ops->set_timeout(socket, connection_state(0));
|
socket->ops->set_timeout(socket, connection_state(0));
|
||||||
socket->ops->set_state(socket, state);
|
socket->ops->set_state(socket, state);
|
||||||
|
|
||||||
|
del_from_list(&ref);
|
||||||
|
if (ref.socket == NULL) {
|
||||||
|
/* socket->ops->set_state deleted the socket. */
|
||||||
|
if (is_buffer_new)
|
||||||
|
mem_free(buffer);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if (socket->read_buffer && buffer != socket->read_buffer)
|
if (socket->read_buffer && buffer != socket->read_buffer)
|
||||||
mem_free(socket->read_buffer);
|
mem_free(socket->read_buffer);
|
||||||
socket->read_buffer = buffer;
|
socket->read_buffer = buffer;
|
||||||
|
Loading…
Reference in New Issue
Block a user