mirror of
https://github.com/systemd/systemd.git
synced 2025-01-10 05:18:17 +03:00
network: introduce reference counter for Request object
Currently, all Request object are always owned by Manager, and freed when it is processed, especially, soon after a netlink message is sent. So, it is not necessary to introduce the reference counter. In a later commit, the Request object will _not_ be freed at the time when a netlink message is sent, but assigned to the relevant netlink slot as a userdata, and will be freed when a reply is received. So, the owner of the Request object is changed in its lifetime. In that case, it is convenient that the object has reference counter to avoid memleak or double free.
This commit is contained in:
parent
ff51134c93
commit
e9ef9a1484
@ -92,7 +92,7 @@ static Request *request_free(Request *req) {
|
||||
return mfree(req);
|
||||
}
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_free);
|
||||
DEFINE_TRIVIAL_REF_UNREF_FUNC(Request, request, request_free);
|
||||
|
||||
void request_drop(Request *req) {
|
||||
if (!req)
|
||||
@ -101,7 +101,7 @@ void request_drop(Request *req) {
|
||||
if (req->message_counter)
|
||||
(*req->message_counter)--;
|
||||
|
||||
request_free(req);
|
||||
request_unref(req);
|
||||
}
|
||||
|
||||
static void request_hash_func(const Request *req, struct siphash *state) {
|
||||
@ -238,13 +238,13 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
||||
Request,
|
||||
request_hash_func,
|
||||
request_compare_func,
|
||||
request_free);
|
||||
request_unref);
|
||||
|
||||
int netdev_queue_request(
|
||||
NetDev *netdev,
|
||||
Request **ret) {
|
||||
|
||||
_cleanup_(request_freep) Request *req = NULL;
|
||||
_cleanup_(request_unrefp) Request *req = NULL;
|
||||
Request *existing;
|
||||
int r;
|
||||
|
||||
@ -256,6 +256,7 @@ int netdev_queue_request(
|
||||
return -ENOMEM;
|
||||
|
||||
*req = (Request) {
|
||||
.n_ref = 1,
|
||||
.netdev = netdev_ref(netdev),
|
||||
.type = REQUEST_TYPE_NETDEV_INDEPENDENT,
|
||||
.consume_object = true,
|
||||
@ -291,7 +292,7 @@ int link_queue_request(
|
||||
link_netlink_message_handler_t netlink_handler,
|
||||
Request **ret) {
|
||||
|
||||
_cleanup_(request_freep) Request *req = NULL;
|
||||
_cleanup_(request_unrefp) Request *req = NULL;
|
||||
Request *existing;
|
||||
int r;
|
||||
|
||||
@ -324,6 +325,7 @@ int link_queue_request(
|
||||
}
|
||||
|
||||
*req = (Request) {
|
||||
.n_ref = 1,
|
||||
.link = link_ref(link),
|
||||
.type = type,
|
||||
.object = object,
|
||||
@ -439,7 +441,7 @@ int manager_process_requests(sd_event_source *s, void *userdata) {
|
||||
link_enter_failed(req->link);
|
||||
} else if (r > 0) {
|
||||
ordered_set_remove(manager->request_queue, req);
|
||||
request_free(req);
|
||||
request_unref(req);
|
||||
processed = true;
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ typedef enum RequestType {
|
||||
} RequestType;
|
||||
|
||||
typedef struct Request {
|
||||
unsigned n_ref;
|
||||
|
||||
Link *link;
|
||||
RequestType type;
|
||||
bool consume_object;
|
||||
@ -68,6 +70,10 @@ typedef struct Request {
|
||||
link_netlink_message_handler_t netlink_handler;
|
||||
} Request;
|
||||
|
||||
Request *request_ref(Request *req);
|
||||
Request *request_unref(Request *req);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(Request*, request_unref);
|
||||
|
||||
void request_drop(Request *req);
|
||||
|
||||
int netdev_queue_request(
|
||||
|
Loading…
Reference in New Issue
Block a user