mirror of
https://github.com/transmission/transmission
synced 2024-12-25 09:13:06 +00:00
Fix pending_request_data memleak in Session (GTK client) (#2139)
This commit is contained in:
parent
7c3f8b5701
commit
e144ad6da8
1 changed files with 20 additions and 26 deletions
|
@ -91,7 +91,7 @@ public:
|
||||||
void add_torrent(tr_torrent* tor, bool do_notify);
|
void add_torrent(tr_torrent* tor, bool do_notify);
|
||||||
bool add_from_url(Glib::ustring const& uri);
|
bool add_from_url(Glib::ustring const& uri);
|
||||||
|
|
||||||
void send_rpc_request(tr_variant const* request, int tag, std::function<void(tr_variant*)> const& response_func);
|
void send_rpc_request(tr_variant const* request, int64_t tag, std::function<void(tr_variant*)> const& response_func);
|
||||||
|
|
||||||
void commit_prefs_change(tr_quark key);
|
void commit_prefs_change(tr_quark key);
|
||||||
|
|
||||||
|
@ -1631,36 +1631,31 @@ void Session::set_pref(tr_quark const key, double newval)
|
||||||
namespace
|
namespace
|
||||||
{
|
{
|
||||||
|
|
||||||
int nextTag = 1;
|
int64_t nextTag = 1;
|
||||||
|
|
||||||
typedef void (*server_response_func)(Session* core, tr_variant* response, gpointer user_data);
|
typedef void (*server_response_func)(Session* core, tr_variant* response, gpointer user_data);
|
||||||
|
|
||||||
struct pending_request_data
|
std::map<int64_t, std::function<void(tr_variant*)>> pendingRequests;
|
||||||
{
|
|
||||||
void* impl;
|
|
||||||
std::function<void(tr_variant*)> response_func;
|
|
||||||
};
|
|
||||||
|
|
||||||
std::map<int, pending_request_data*> pendingRequests;
|
|
||||||
|
|
||||||
bool core_read_rpc_response_idle(tr_variant* response)
|
bool core_read_rpc_response_idle(tr_variant* response)
|
||||||
{
|
{
|
||||||
int64_t intVal;
|
int64_t tag;
|
||||||
|
|
||||||
if (tr_variantDictFindInt(response, TR_KEY_tag, &intVal))
|
if (tr_variantDictFindInt(response, TR_KEY_tag, &tag))
|
||||||
{
|
{
|
||||||
int const tag = (int)intVal;
|
if (auto const data_it = pendingRequests.find(tag); data_it != pendingRequests.end())
|
||||||
auto const data_it = pendingRequests.find(tag);
|
|
||||||
|
|
||||||
if (data_it != pendingRequests.end())
|
|
||||||
{
|
{
|
||||||
if (auto const& data = data_it->second; data->response_func)
|
if (auto const& response_func = data_it->second; response_func)
|
||||||
{
|
{
|
||||||
data->response_func(response);
|
response_func(response);
|
||||||
}
|
}
|
||||||
|
|
||||||
pendingRequests.erase(data_it);
|
pendingRequests.erase(data_it);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_warning("Pending RPC request for tag %" PRId64 " not found", tag);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
tr_variantFree(response);
|
tr_variantFree(response);
|
||||||
|
@ -1670,7 +1665,7 @@ bool core_read_rpc_response_idle(tr_variant* response)
|
||||||
|
|
||||||
void core_read_rpc_response(tr_session* /*session*/, tr_variant* response, void* /*user_data*/)
|
void core_read_rpc_response(tr_session* /*session*/, tr_variant* response, void* /*user_data*/)
|
||||||
{
|
{
|
||||||
tr_variant* response_copy = new tr_variant(*response);
|
tr_variant* response_copy = new tr_variant(std::move(*response));
|
||||||
|
|
||||||
tr_variantInitBool(response, false);
|
tr_variantInitBool(response, false);
|
||||||
|
|
||||||
|
@ -1679,7 +1674,10 @@ void core_read_rpc_response(tr_session* /*session*/, tr_variant* response, void*
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
void Session::Impl::send_rpc_request(tr_variant const* request, int tag, std::function<void(tr_variant*)> const& response_func)
|
void Session::Impl::send_rpc_request(
|
||||||
|
tr_variant const* request,
|
||||||
|
int64_t tag,
|
||||||
|
std::function<void(tr_variant*)> const& response_func)
|
||||||
{
|
{
|
||||||
if (session_ == nullptr)
|
if (session_ == nullptr)
|
||||||
{
|
{
|
||||||
|
@ -1688,10 +1686,7 @@ void Session::Impl::send_rpc_request(tr_variant const* request, int tag, std::fu
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* remember this request */
|
/* remember this request */
|
||||||
auto* const data = new pending_request_data();
|
pendingRequests.emplace(tag, response_func);
|
||||||
data->impl = this;
|
|
||||||
data->response_func = response_func;
|
|
||||||
pendingRequests.emplace(tag, data);
|
|
||||||
|
|
||||||
/* make the request */
|
/* make the request */
|
||||||
#ifdef DEBUG_RPC
|
#ifdef DEBUG_RPC
|
||||||
|
@ -1703,7 +1698,7 @@ void Session::Impl::send_rpc_request(tr_variant const* request, int tag, std::fu
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
tr_rpc_request_exec_json(session_, request, core_read_rpc_response, GINT_TO_POINTER(tag));
|
tr_rpc_request_exec_json(session_, request, core_read_rpc_response, nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1713,8 +1708,7 @@ void Session::Impl::send_rpc_request(tr_variant const* request, int tag, std::fu
|
||||||
|
|
||||||
void Session::port_test()
|
void Session::port_test()
|
||||||
{
|
{
|
||||||
int const tag = nextTag;
|
auto const tag = nextTag++;
|
||||||
++nextTag;
|
|
||||||
|
|
||||||
tr_variant request;
|
tr_variant request;
|
||||||
tr_variantInitDict(&request, 2);
|
tr_variantInitDict(&request, 2);
|
||||||
|
|
Loading…
Reference in a new issue