[vlc-commits] httpd: use atomic reference count for hosts
Rémi Denis-Courmont
git at videolan.org
Sun Jun 17 20:13:14 CEST 2018
vlc | branch: master | Rémi Denis-Courmont <remi at remlab.net> | Sun Jun 17 20:41:53 2018 +0300| [4c3ecdb7cc2dc220f1402506bcc5b1bf0e3d106f] | committer: Rémi Denis-Courmont
httpd: use atomic reference count for hosts
And simplify accordingly. The reference count is actually handled under
the httpd.lock global mutex. The atomicity is only because the
reference count doubles as thread death flag.
> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=4c3ecdb7cc2dc220f1402506bcc5b1bf0e3d106f
---
src/network/httpd.c | 30 ++++++++++--------------------
1 file changed, 10 insertions(+), 20 deletions(-)
diff --git a/src/network/httpd.c b/src/network/httpd.c
index b74fc05d1c..768c744bd5 100644
--- a/src/network/httpd.c
+++ b/src/network/httpd.c
@@ -27,6 +27,8 @@
# include "config.h"
#endif
+#include <stdatomic.h>
+
#include <vlc_common.h>
#include <vlc_httpd.h>
@@ -77,7 +79,7 @@ struct httpd_host_t
struct vlc_list node;
/* ref count */
- unsigned i_ref;
+ atomic_uint ref;
/* address/port and socket for listening at connections */
int *fds;
@@ -932,13 +934,8 @@ static httpd_host_t *httpd_HostCreate(vlc_object_t *p_this,
|| (host->p_tls != NULL) != (p_tls != NULL))
continue;
- /* Increase existing matching host reference count.
- * The reference count is written under both the global httpd and the
- * host lock. It is read with either or both locks held. The global
- * lock is always acquired first. */
- vlc_mutex_lock(&host->lock);
- host->i_ref++;
- vlc_mutex_unlock(&host->lock);
+ /* Increase existing matching host reference count. */
+ atomic_fetch_add_explicit(&host->ref, 1, memory_order_relaxed);
vlc_mutex_unlock(&httpd.mutex);
vlc_UrlClean(&url);
@@ -954,7 +951,7 @@ static httpd_host_t *httpd_HostCreate(vlc_object_t *p_this,
vlc_mutex_init(&host->lock);
vlc_cond_init(&host->wait);
- host->i_ref = 1;
+ atomic_init(&host->ref, 1);
host->fds = net_ListenTCP(p_this, url.psz_host, port);
if (!host->fds) {
@@ -1003,16 +1000,9 @@ error:
/* delete a host */
void httpd_HostDelete(httpd_host_t *host)
{
- bool delete = false;
-
vlc_mutex_lock(&httpd.mutex);
- vlc_mutex_lock(&host->lock);
- host->i_ref--;
- if (host->i_ref == 0)
- delete = true;
- vlc_mutex_unlock(&host->lock);
- if (!delete) {
+ if (atomic_fetch_sub_explicit(&host->ref, 1, memory_order_relaxed) > 1) {
/* still used */
vlc_mutex_unlock(&httpd.mutex);
msg_Dbg(host, "httpd_HostDelete: host still in use");
@@ -1695,6 +1685,7 @@ static void httpdLoop(httpd_host_t *host)
ufd[nfd].revents = 0;
}
+ vlc_mutex_lock(&host->lock);
/* add all socket that should be read/write and close dead connection */
while (host->i_url <= 0) {
mutex_cleanup_push(&host->lock);
@@ -2036,6 +2027,7 @@ static void httpdLoop(httpd_host_t *host)
TAB_APPEND(host->i_client, host->client, cl);
}
+ vlc_mutex_unlock(&host->lock);
vlc_restorecancel(canc);
}
@@ -2043,10 +2035,8 @@ static void* httpd_HostThread(void *data)
{
httpd_host_t *host = data;
- vlc_mutex_lock(&host->lock);
- while (host->i_ref > 0)
+ while (atomic_load_explicit(&host->ref, memory_order_relaxed) > 0)
httpdLoop(host);
- vlc_mutex_unlock(&host->lock);
return NULL;
}
More information about the vlc-commits
mailing list