summaryrefslogtreecommitdiffstats
path: root/src/server/reference.c
diff options
context:
space:
mode:
authorSimon Rettberg2020-07-27 12:56:35 +0200
committerSimon Rettberg2020-07-27 12:56:35 +0200
commit1f212fa1fd0a381b42175dc1bac79baa164e1e45 (patch)
tree7d911d7fe40817cbb433acebc3ed735eafe9c6df /src/server/reference.c
parent[FUSE] Tweak timeout values to prevent stale status file (diff)
parent[SERVER] Fix: NULL pointer access in saveLoadAllCacheMaps() (diff)
downloaddnbd3-1f212fa1fd0a381b42175dc1bac79baa164e1e45.tar.gz
dnbd3-1f212fa1fd0a381b42175dc1bac79baa164e1e45.tar.xz
dnbd3-1f212fa1fd0a381b42175dc1bac79baa164e1e45.zip
Merge branch 'no-working-flag' into fuse_ll
Diffstat (limited to 'src/server/reference.c')
-rw-r--r--src/server/reference.c33
1 files changed, 33 insertions, 0 deletions
diff --git a/src/server/reference.c b/src/server/reference.c
new file mode 100644
index 0000000..64109ca
--- /dev/null
+++ b/src/server/reference.c
@@ -0,0 +1,33 @@
+#ifndef unlikely
+#define unlikely(x) (x)
+#endif
+#include "reference.h"
+#include <stdio.h>
+#include <stdlib.h>
+
+void ref_init( ref *reference, void ( *freefun )( ref * ), long count )
+{
+ reference->count = count;
+ reference->free = freefun;
+}
+
+_Noreturn void _ref_error( const char *message )
+{
+ fprintf( stderr, "%s\n", message );
+ abort();
+}
+
+void ref_setref( weakref *weakref, ref *ref )
+{
+ union _aligned_ref_ *new_weakref = 0;
+ if ( ref ) {
+ ( new_weakref = aligned_ref( ref->_aligned_ref ) )->ref = ref;
+ ref->count += sizeof( union _aligned_ref_ ) + 1;
+ }
+ char *old_weakref = (char *)atomic_exchange( weakref, new_weakref );
+ if ( !old_weakref )
+ return;
+ struct _ref_ *old_ref = aligned_ref( old_weakref )->ref;
+ old_ref->count += old_weakref - (char *)aligned_ref( old_weakref ) - sizeof( union _aligned_ref_ );
+ ref_put( old_ref );
+}