Add memory management for mtproto_connections
Mark connections for destruction on close and free all allocated memory only once all incoming queries are read, since those queries will still access data on the current mtproto_connection and cause segmentation faults.
This commit is contained in:
parent
1e6598c11c
commit
c144484fd5
3 changed files with 52 additions and 5 deletions
|
@ -1855,14 +1855,18 @@ struct connection_methods mtproto_methods = {
|
|||
.close = rpc_close
|
||||
};
|
||||
|
||||
// TODO: use a list or tree instead
|
||||
struct mtproto_connection *Cs[100];
|
||||
|
||||
/**
|
||||
* Create a new struct mtproto_connection connection using the giving datacenter for authorization and
|
||||
* session handling
|
||||
*/
|
||||
struct mtproto_connection *mtproto_new(struct dc *DC, int fd, struct telegram *tg)
|
||||
{
|
||||
// init
|
||||
static int cs = 0;
|
||||
struct mtproto_connection *mtp = talloc(sizeof(struct mtproto_connection));
|
||||
Cs[cs++] = mtp;
|
||||
memset(mtp, 0, sizeof(struct mtproto_connection));
|
||||
mtp->packet_buffer = mtp->__packet_buffer + 16;
|
||||
mtp->connection = fd_create_connection(DC, fd, tg, &mtproto_methods, mtp);
|
||||
|
@ -1888,10 +1892,43 @@ void mtproto_connect(struct mtproto_connection *c)
|
|||
/**
|
||||
* Free all used resources and close the connection
|
||||
*/
|
||||
void mtproto_close(struct mtproto_connection *c)
|
||||
{
|
||||
void mtproto_close(struct mtproto_connection *mtp) {
|
||||
logprintf ("closing mtproto_connection...\n");
|
||||
mtp->destroy = 1;
|
||||
|
||||
// TODO: Use Pings?
|
||||
// stop_ping_timer (c->connection);
|
||||
fd_close_connection(c->connection);
|
||||
|
||||
// TODO: Set destruction timeout?
|
||||
// add_destruction_timer (c, 5000)
|
||||
/*
|
||||
Timout:
|
||||
- alle queries und acks löschen?
|
||||
- was passiert wenn eine antwort auf eine query
|
||||
in einer neuen instanz ankommt?
|
||||
*/
|
||||
}
|
||||
|
||||
void mtproto_destroy (struct mtproto_connection *self) {
|
||||
logprintf("destroying mtproto_connection: %p\n", self);
|
||||
|
||||
// TODO: Remove all pending timers, queries, acks
|
||||
// TODO: Call destruction callback
|
||||
fd_close_connection(self->connection);
|
||||
tfree(self->connection, sizeof(struct connection));
|
||||
}
|
||||
|
||||
void mtproto_free_closed () {
|
||||
int i;
|
||||
for (i = 0; i < 100; i++) {
|
||||
if (Cs[i] == NULL) continue;
|
||||
struct mtproto_connection *c = Cs[i];
|
||||
logprintf ("checking mtproto_connection %d: c_state:%d destroy:%d, quries_num:%d\n",
|
||||
i, c->c_state, c->destroy, c->queries_num);
|
||||
if (c->destroy == 0) continue;
|
||||
if (c->queries_num > 0) continue;
|
||||
mtproto_destroy (c);
|
||||
Cs[i] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -156,6 +156,8 @@ enum dc_state {
|
|||
// forward-declarations
|
||||
struct timespec;
|
||||
struct telegram;
|
||||
struct mtproto_connection;
|
||||
void mtproto_destroy (struct mtproto_connection *self);
|
||||
|
||||
#define DECRYPT_BUFFER_INTS 16384
|
||||
#define ENCRYPT_BUFFER_INTS 16384
|
||||
|
@ -501,4 +503,7 @@ static inline void hexdump_out (struct mtproto_connection *self) {
|
|||
#endif
|
||||
void my_clock_gettime (int clock_id, struct timespec *T);
|
||||
|
||||
void mtproto_free_closed ();
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -274,7 +274,12 @@ void on_authorized(struct mtproto_connection *c, void *data)
|
|||
|
||||
void telegram_read_input (struct telegram *instance)
|
||||
{
|
||||
return try_read(instance->connection->connection);
|
||||
try_read(instance->connection->connection);
|
||||
mtproto_free_closed();
|
||||
// free all mtproto_connections that may have errored through
|
||||
// a received query
|
||||
}
|
||||
|
||||
void telegram_set_proxy(struct telegram *instance, int fd)
|
||||
{
|
||||
struct dc *DC_working = telegram_get_working_dc (instance);
|
||||
|
|
Loading…
Add table
Reference in a new issue