1
0
mirror of https://github.com/systemd/systemd.git synced 2024-11-08 11:27:32 +03:00

sd-dhcp-client: return NULL from _unref() like the other sd-* libraries

Let's keep this behavior consistent across our libraries.

In order to keep the refcounting working, a DONT_DESTROY macro similar
to the one in sd-bus was introduced.
This commit is contained in:
Tom Gundersen 2014-05-22 15:18:28 +02:00
parent 3577de7ac3
commit 574cc92888
2 changed files with 35 additions and 34 deletions

View File

@ -27,6 +27,7 @@
#include "socket-util.h" #include "socket-util.h"
#include "sd-dhcp-client.h"
#include "dhcp-protocol.h" #include "dhcp-protocol.h"
int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t xid); int dhcp_network_bind_raw_socket(int index, union sockaddr_union *link, uint32_t xid);
@ -56,4 +57,13 @@ void dhcp_packet_append_ip_headers(DHCPPacket *packet, be32_t source_addr,
int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum); int dhcp_packet_verify_headers(DHCPPacket *packet, size_t len, bool checksum);
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_unref);
#define _cleanup_dhcp_client_unref_ _cleanup_(sd_dhcp_client_unrefp)
/* If we are invoking callbacks of a dhcp-client, ensure unreffing the
* client from the callback doesn't destroy the object we are working
* on */
#define DHCP_CLIENT_DONT_DESTROY(client) \
_cleanup_dhcp_client_unref_ _unused_ sd_dhcp_client *_dont_destroy_##client = sd_dhcp_client_ref(client)
#define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__) #define log_dhcp_client(client, fmt, ...) log_meta(LOG_DEBUG, __FILE__, __LINE__, __func__, "DHCP CLIENT (0x%x): " fmt, client->xid, ##__VA_ARGS__)

View File

@ -82,7 +82,7 @@ static int client_receive_message_raw(sd_event_source *s, int fd,
uint32_t revents, void *userdata); uint32_t revents, void *userdata);
static int client_receive_message_udp(sd_event_source *s, int fd, static int client_receive_message_udp(sd_event_source *s, int fd,
uint32_t revents, void *userdata); uint32_t revents, void *userdata);
static sd_dhcp_client *client_stop(sd_dhcp_client *client, int error); static void client_stop(sd_dhcp_client *client, int error);
int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb, int sd_dhcp_client_set_callback(sd_dhcp_client *client, sd_dhcp_client_cb_t cb,
void *userdata) { void *userdata) {
@ -153,6 +153,7 @@ int sd_dhcp_client_set_index(sd_dhcp_client *client, int interface_index) {
int sd_dhcp_client_set_mac(sd_dhcp_client *client, int sd_dhcp_client_set_mac(sd_dhcp_client *client,
const struct ether_addr *addr) { const struct ether_addr *addr) {
DHCP_CLIENT_DONT_DESTROY(client);
bool need_restart = false; bool need_restart = false;
assert_return(client, -EINVAL); assert_return(client, -EINVAL);
@ -165,12 +166,9 @@ int sd_dhcp_client_set_mac(sd_dhcp_client *client,
log_dhcp_client(client, "Changing MAC address on running DHCP " log_dhcp_client(client, "Changing MAC address on running DHCP "
"client, restarting"); "client, restarting");
need_restart = true; need_restart = true;
client = client_stop(client, DHCP_EVENT_STOP); client_stop(client, DHCP_EVENT_STOP);
} }
if (!client)
return 0;
memcpy(&client->client_id.mac_addr, addr, ETH_ALEN); memcpy(&client->client_id.mac_addr, addr, ETH_ALEN);
client->client_id.type = 0x01; client->client_id.type = 0x01;
@ -194,14 +192,9 @@ int sd_dhcp_client_get_lease(sd_dhcp_client *client, sd_dhcp_lease **ret) {
return 0; return 0;
} }
static sd_dhcp_client *client_notify(sd_dhcp_client *client, int event) { static void client_notify(sd_dhcp_client *client, int event) {
if (client->cb) { if (client->cb)
client = sd_dhcp_client_ref(client);
client->cb(client, event, client->userdata); client->cb(client, event, client->userdata);
client = sd_dhcp_client_unref(client);
}
return client;
} }
static int client_initialize(sd_dhcp_client *client) { static int client_initialize(sd_dhcp_client *client) {
@ -229,8 +222,8 @@ static int client_initialize(sd_dhcp_client *client) {
return 0; return 0;
} }
static sd_dhcp_client *client_stop(sd_dhcp_client *client, int error) { static void client_stop(sd_dhcp_client *client, int error) {
assert_return(client, NULL); assert(client);
if (error < 0) if (error < 0)
log_dhcp_client(client, "STOPPED: %s", strerror(-error)); log_dhcp_client(client, "STOPPED: %s", strerror(-error));
@ -248,12 +241,9 @@ static sd_dhcp_client *client_stop(sd_dhcp_client *client, int error) {
} }
} }
client = client_notify(client, error); client_notify(client, error);
if (client) client_initialize(client);
client_initialize(client);
return client;
} }
static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret, static int client_message_init(sd_dhcp_client *client, DHCPPacket **ret,
@ -530,6 +520,7 @@ static int client_start(sd_dhcp_client *client);
static int client_timeout_resend(sd_event_source *s, uint64_t usec, static int client_timeout_resend(sd_event_source *s, uint64_t usec,
void *userdata) { void *userdata) {
sd_dhcp_client *client = userdata; sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
usec_t next_timeout = 0; usec_t next_timeout = 0;
uint64_t time_now; uint64_t time_now;
uint32_t time_left; uint32_t time_left;
@ -737,13 +728,14 @@ static int client_start(sd_dhcp_client *client) {
static int client_timeout_expire(sd_event_source *s, uint64_t usec, static int client_timeout_expire(sd_event_source *s, uint64_t usec,
void *userdata) { void *userdata) {
sd_dhcp_client *client = userdata; sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
log_dhcp_client(client, "EXPIRED"); log_dhcp_client(client, "EXPIRED");
client = client_notify(client, DHCP_EVENT_EXPIRED); client_notify(client, DHCP_EVENT_EXPIRED);
/* lease was lost, start over if not freed or stopped in callback */ /* lease was lost, start over if not freed or stopped in callback */
if (client && client->state != DHCP_STATE_STOPPED) { if (client->state != DHCP_STATE_STOPPED) {
client_initialize(client); client_initialize(client);
client_start(client); client_start(client);
} }
@ -753,6 +745,7 @@ static int client_timeout_expire(sd_event_source *s, uint64_t usec,
static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) { static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata) {
sd_dhcp_client *client = userdata; sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
int r; int r;
client->receive_message = sd_event_source_unref(client->receive_message); client->receive_message = sd_event_source_unref(client->receive_message);
@ -774,6 +767,7 @@ static int client_timeout_t2(sd_event_source *s, uint64_t usec, void *userdata)
static int client_timeout_t1(sd_event_source *s, uint64_t usec, static int client_timeout_t1(sd_event_source *s, uint64_t usec,
void *userdata) { void *userdata) {
sd_dhcp_client *client = userdata; sd_dhcp_client *client = userdata;
DHCP_CLIENT_DONT_DESTROY(client);
int r; int r;
client->state = DHCP_STATE_RENEWING; client->state = DHCP_STATE_RENEWING;
@ -1045,6 +1039,7 @@ static int client_set_lease_timeouts(sd_dhcp_client *client) {
static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message, static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
int len) { int len) {
DHCP_CLIENT_DONT_DESTROY(client);
int r = 0, notify_event = 0; int r = 0, notify_event = 0;
assert(client); assert(client);
@ -1154,9 +1149,8 @@ static int client_handle_message(sd_dhcp_client *client, DHCPMessage *message,
goto error; goto error;
if (notify_event) { if (notify_event) {
client = client_notify(client, notify_event); client_notify(client, notify_event);
if (!client || if (client->state == DHCP_STATE_STOPPED)
client->state == DHCP_STATE_STOPPED)
return 0; return 0;
} }
@ -1303,10 +1297,12 @@ int sd_dhcp_client_start(sd_dhcp_client *client) {
} }
int sd_dhcp_client_stop(sd_dhcp_client *client) { int sd_dhcp_client_stop(sd_dhcp_client *client) {
DHCP_CLIENT_DONT_DESTROY(client);
assert_return(client, -EINVAL); assert_return(client, -EINVAL);
if (client_stop(client, DHCP_EVENT_STOP)) client_stop(client, DHCP_EVENT_STOP);
client->state = DHCP_STATE_STOPPED; client->state = DHCP_STATE_STOPPED;
return 0; return 0;
} }
@ -1355,7 +1351,7 @@ sd_dhcp_client *sd_dhcp_client_ref(sd_dhcp_client *client) {
sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) { sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
if (client && REFCNT_DEC(client->n_ref) <= 0) { if (client && REFCNT_DEC(client->n_ref) <= 0) {
log_dhcp_client(client, "UNREF"); log_dhcp_client(client, "FREE");
client_initialize(client); client_initialize(client);
@ -1368,18 +1364,13 @@ sd_dhcp_client *sd_dhcp_client_unref(sd_dhcp_client *client) {
free(client->req_opts); free(client->req_opts);
free(client); free(client);
return NULL;
} }
return client; return NULL;
} }
DEFINE_TRIVIAL_CLEANUP_FUNC(sd_dhcp_client*, sd_dhcp_client_unref);
#define _cleanup_dhcp_client_free_ _cleanup_(sd_dhcp_client_unrefp)
int sd_dhcp_client_new(sd_dhcp_client **ret) { int sd_dhcp_client_new(sd_dhcp_client **ret) {
_cleanup_dhcp_client_free_ sd_dhcp_client *client = NULL; _cleanup_dhcp_client_unref_ sd_dhcp_client *client = NULL;
assert_return(ret, -EINVAL); assert_return(ret, -EINVAL);