mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-04-01 05:13:06 +02:00
Add caching for the receiver addresses for g_socket_receive_from()
https://bugzilla.gnome.org/show_bug.cgi?id=668842
This commit is contained in:
parent
df1e049792
commit
2bba1da306
@ -149,6 +149,9 @@ enum
|
|||||||
PROP_MULTICAST_TTL
|
PROP_MULTICAST_TTL
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* Size of the receiver cache for g_socket_receive_from() */
|
||||||
|
#define RECV_ADDR_CACHE_SIZE 8
|
||||||
|
|
||||||
struct _GSocketPrivate
|
struct _GSocketPrivate
|
||||||
{
|
{
|
||||||
GSocketFamily family;
|
GSocketFamily family;
|
||||||
@ -174,6 +177,13 @@ struct _GSocketPrivate
|
|||||||
int selected_events;
|
int selected_events;
|
||||||
GList *requested_conditions; /* list of requested GIOCondition * */
|
GList *requested_conditions; /* list of requested GIOCondition * */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
struct {
|
||||||
|
GSocketAddress *addr;
|
||||||
|
struct sockaddr *native;
|
||||||
|
gint native_len;
|
||||||
|
guint64 last_used;
|
||||||
|
} recv_addr_cache[RECV_ADDR_CACHE_SIZE];
|
||||||
};
|
};
|
||||||
|
|
||||||
static int
|
static int
|
||||||
@ -718,6 +728,7 @@ static void
|
|||||||
g_socket_finalize (GObject *object)
|
g_socket_finalize (GObject *object)
|
||||||
{
|
{
|
||||||
GSocket *socket = G_SOCKET (object);
|
GSocket *socket = G_SOCKET (object);
|
||||||
|
gint i;
|
||||||
|
|
||||||
g_clear_error (&socket->priv->construct_error);
|
g_clear_error (&socket->priv->construct_error);
|
||||||
|
|
||||||
@ -738,6 +749,15 @@ g_socket_finalize (GObject *object)
|
|||||||
g_assert (socket->priv->requested_conditions == NULL);
|
g_assert (socket->priv->requested_conditions == NULL);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
for (i = 0; i < RECV_ADDR_CACHE_SIZE; i++)
|
||||||
|
{
|
||||||
|
if (socket->priv->recv_addr_cache[i].addr)
|
||||||
|
{
|
||||||
|
g_object_unref (socket->priv->recv_addr_cache[i].addr);
|
||||||
|
g_free (socket->priv->recv_addr_cache[i].native);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (G_OBJECT_CLASS (g_socket_parent_class)->finalize)
|
if (G_OBJECT_CLASS (g_socket_parent_class)->finalize)
|
||||||
(*G_OBJECT_CLASS (g_socket_parent_class)->finalize) (object);
|
(*G_OBJECT_CLASS (g_socket_parent_class)->finalize) (object);
|
||||||
}
|
}
|
||||||
@ -3898,6 +3918,60 @@ g_socket_send_message (GSocket *socket,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GSocketAddress *
|
||||||
|
cache_recv_address (GSocket *socket, struct sockaddr *native, int native_len)
|
||||||
|
{
|
||||||
|
GSocketAddress *saddr;
|
||||||
|
gint i;
|
||||||
|
guint64 oldest_time = G_MAXUINT64;
|
||||||
|
gint oldest_index = 0;
|
||||||
|
|
||||||
|
if (native_len <= 0)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
saddr = NULL;
|
||||||
|
for (i = 0; i < RECV_ADDR_CACHE_SIZE; i++)
|
||||||
|
{
|
||||||
|
GSocketAddress *tmp = socket->priv->recv_addr_cache[i].addr;
|
||||||
|
gpointer tmp_native = socket->priv->recv_addr_cache[i].native;
|
||||||
|
gint tmp_native_len = socket->priv->recv_addr_cache[i].native_len;
|
||||||
|
|
||||||
|
if (!tmp)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (tmp_native_len != native_len)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (memcmp (tmp_native, native, native_len) == 0)
|
||||||
|
{
|
||||||
|
saddr = g_object_ref (tmp);
|
||||||
|
socket->priv->recv_addr_cache[i].last_used = g_get_monotonic_time ();
|
||||||
|
return saddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (socket->priv->recv_addr_cache[i].last_used < oldest_time)
|
||||||
|
{
|
||||||
|
oldest_time = socket->priv->recv_addr_cache[i].last_used;
|
||||||
|
oldest_index = i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
saddr = g_socket_address_new_from_native (native, native_len);
|
||||||
|
|
||||||
|
if (socket->priv->recv_addr_cache[oldest_index].addr)
|
||||||
|
{
|
||||||
|
g_object_unref (socket->priv->recv_addr_cache[oldest_index].addr);
|
||||||
|
g_free (socket->priv->recv_addr_cache[oldest_index].native);
|
||||||
|
}
|
||||||
|
|
||||||
|
socket->priv->recv_addr_cache[oldest_index].native = g_memdup (native, native_len);
|
||||||
|
socket->priv->recv_addr_cache[oldest_index].native_len = native_len;
|
||||||
|
socket->priv->recv_addr_cache[oldest_index].addr = g_object_ref (saddr);
|
||||||
|
socket->priv->recv_addr_cache[oldest_index].last_used = g_get_monotonic_time ();
|
||||||
|
|
||||||
|
return saddr;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* g_socket_receive_message:
|
* g_socket_receive_message:
|
||||||
* @socket: a #GSocket
|
* @socket: a #GSocket
|
||||||
@ -4120,11 +4194,7 @@ g_socket_receive_message (GSocket *socket,
|
|||||||
/* decode address */
|
/* decode address */
|
||||||
if (address != NULL)
|
if (address != NULL)
|
||||||
{
|
{
|
||||||
if (msg.msg_namelen > 0)
|
*address = cache_recv_address (socket, msg.msg_name, msg.msg_namelen);
|
||||||
*address = g_socket_address_new_from_native (msg.msg_name,
|
|
||||||
msg.msg_namelen);
|
|
||||||
else
|
|
||||||
*address = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* decode control messages */
|
/* decode control messages */
|
||||||
@ -4257,10 +4327,7 @@ g_socket_receive_message (GSocket *socket,
|
|||||||
/* decode address */
|
/* decode address */
|
||||||
if (address != NULL)
|
if (address != NULL)
|
||||||
{
|
{
|
||||||
if (addrlen > 0)
|
*address = cache_recv_address (socket, &addr, addrlen);
|
||||||
*address = g_socket_address_new_from_native (&addr, addrlen);
|
|
||||||
else
|
|
||||||
*address = NULL;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* capture the flags */
|
/* capture the flags */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user