Helps to track potential memory leaks.
bool admin_flush(PgSocket *admin, PktBuf *buf, const char *desc) /* _MUSTCHECK */;
bool admin_ready(PgSocket *admin, const char *desc) _MUSTCHECK;
void admin_handle_cancel(PgSocket *client);
+void admin_cleanup(void);
void init_caches(void);
+void objects_cleanup(void);
+
#define SEND_PasswordMessage(res, sk, psw) \
SEND_wrap(512, pktbuf_write_PasswordMessage, res, sk, psw)
-
+void pktbuf_cleanup(void);
return sbuf->ops->sbufio_close(sbuf);
}
+void sbuf_cleanup(void);
+
void varcache_fill_unset(VarCache *src, PgSocket *dst);
void varcache_clean(VarCache *cache);
void varcache_add_params(PktBuf *pkt, VarCache *vars);
+void varcache_deinit(void);
/* only valid during processing */
static const char *current_query;
+void admin_cleanup(void)
+{
+ regfree(&rc_cmd);
+ regfree(&rc_set_str);
+ regfree(&rc_set_word);
+ admin_pool = NULL;
+}
+
static bool syntax_error(PgSocket *admin)
{
return admin_error(admin, "invalid command '%s', use SHOW HELP;",
#include <usual/err.h>
#include <usual/cfparser.h>
#include <usual/getopt.h>
+#include <usual/slab.h>
#ifdef HAVE_SYS_RESOURCE_H
#include <sys/resource.h>
static void remove_pidfile(void)
{
- if (!cf_pidfile[0])
- return;
- unlink(cf_pidfile);
+ if (cf_pidfile) {
+ if (cf_pidfile[0])
+ unlink(cf_pidfile);
+ free(cf_pidfile);
+ cf_pidfile = NULL;
+ }
}
static void check_pidfile(void)
fatal_perror("dns setup failed");
}
+static void xfree(char **ptr_p)
+{
+ if (*ptr_p) {
+ free(*ptr_p);
+ *ptr_p = NULL;
+ }
+}
+
+static void cleanup(void)
+{
+ adns_free_context(adns);
+ adns = NULL;
+
+ admin_cleanup();
+ objects_cleanup();
+ sbuf_cleanup();
+
+ event_base_free(NULL);
+
+ tls_deinit();
+ varcache_deinit();
+ pktbuf_cleanup();
+
+ reset_logging();
+
+ xfree(&cf_username);
+ xfree(&cf_config_file);
+ xfree(&cf_listen_addr);
+ xfree(&cf_unix_socket_dir);
+ xfree(&cf_unix_socket_group);
+ xfree(&cf_auth_file);
+ xfree(&cf_auth_hba_file);
+ xfree(&cf_auth_query);
+ xfree(&cf_server_reset_query);
+ xfree(&cf_server_check_query);
+ xfree(&cf_ignore_startup_params);
+ xfree(&cf_autodb_connstr);
+ xfree(&cf_jobname);
+ xfree(&cf_admin_users);
+ xfree(&cf_stats_users);
+ xfree(&cf_client_tls_protocols);
+ xfree(&cf_client_tls_ca_file);
+ xfree(&cf_client_tls_cert_file);
+ xfree(&cf_client_tls_key_file);
+ xfree(&cf_client_tls_ciphers);
+ xfree(&cf_client_tls_dheparams);
+ xfree(&cf_client_tls_ecdhecurve);
+ xfree(&cf_server_tls_protocols);
+ xfree(&cf_server_tls_ca_file);
+ xfree(&cf_server_tls_cert_file);
+ xfree(&cf_server_tls_key_file);
+ xfree(&cf_server_tls_ciphers);
+
+ xfree((char **)&cf_logfile);
+ xfree((char **)&cf_syslog_ident);
+ xfree((char **)&cf_syslog_facility);
+}
+
/* boot everything */
int main(int argc, char *argv[])
{
while (cf_shutdown < 2)
main_loop_once();
+ cleanup();
+
return 0;
}
}
}
+void objects_cleanup(void)
+{
+ struct List *item;
+ PgDatabase *db;
+
+ /* close can be postpones, just in case call twice */
+ reuse_just_freed_objects();
+ reuse_just_freed_objects();
+
+ statlist_for_each(item, &database_list) {
+ db = container_of(item, PgDatabase, head);
+ db->db_dead = 1;
+ }
+ config_postprocess();
+
+ memset(&login_client_list, 0, sizeof login_client_list);
+ memset(&user_list, 0, sizeof user_list);
+ memset(&database_list, 0, sizeof database_list);
+ memset(&pool_list, 0, sizeof pool_list);
+ memset(&user_tree, 0, sizeof user_tree);
+ memset(&autodatabase_idle_list, 0, sizeof autodatabase_idle_list);
+
+ slab_destroy(server_cache);
+ server_cache = NULL;
+ slab_destroy(client_cache);
+ client_cache = NULL;
+ slab_destroy(db_cache);
+ db_cache = NULL;
+ slab_destroy(pool_cache);
+ pool_cache = NULL;
+ slab_destroy(user_cache);
+ user_cache = NULL;
+ slab_destroy(iobuf_cache);
+ iobuf_cache = NULL;
+}
+
buf->fixed_buf = 1;
}
+static PktBuf *temp_pktbuf;
+
struct PktBuf *pktbuf_temp(void)
{
- static PktBuf *temp_pktbuf;
-
if (!temp_pktbuf)
temp_pktbuf = pktbuf_dynamic(512);
if (!temp_pktbuf)
return temp_pktbuf;
}
+void pktbuf_cleanup(void)
+{
+ pktbuf_free(temp_pktbuf);
+ temp_pktbuf = NULL;
+}
+
bool pktbuf_send_immediate(PktBuf *buf, PgSocket *sk)
{
uint8_t *pos = buf->buf + buf->send_pos;
return 0;
}
+void sbuf_cleanup(void)
+{
+ tls_free(client_accept_base);
+ tls_config_free(client_accept_conf);
+ tls_config_free(server_connect_conf);
+ client_accept_conf = NULL;
+ server_connect_conf = NULL;
+ client_accept_base = NULL;
+}
+
#else
void sbuf_tls_setup(void) { }
bool sbuf_tls_accept(SBuf *sbuf) { return false; }
bool sbuf_tls_connect(SBuf *sbuf, const char *hostname) { return false; }
+void sbuf_cleanup(void)
+{
+}
+
#endif
}
}
+void varcache_deinit(void)
+{
+ strpool_free(vpool);
+ vpool = NULL;
+}
+