summaryrefslogtreecommitdiffstats
path: root/src/server/uplink.c
diff options
context:
space:
mode:
authorSimon Rettberg2014-06-16 19:24:17 +0200
committerSimon Rettberg2014-06-16 19:24:17 +0200
commit49f9218d330f5842fe24bce79267bd2c5b239df3 (patch)
tree74e7b49e9c058145069ac4e2aa6de5d9f2cac3ce /src/server/uplink.c
parent[CLIENT] Debug argument handling in daemon mode (diff)
downloaddnbd3-49f9218d330f5842fe24bce79267bd2c5b239df3.tar.gz
dnbd3-49f9218d330f5842fe24bce79267bd2c5b239df3.tar.xz
dnbd3-49f9218d330f5842fe24bce79267bd2c5b239df3.zip
Improve uplink handling, add code to debug thread creation/destruction, change stupid convention of freeDiskSpace returning 0 on error, which is ambiguous to the disk simply being full...
Diffstat (limited to 'src/server/uplink.c')
-rw-r--r--src/server/uplink.c35
1 files changed, 18 insertions, 17 deletions
diff --git a/src/server/uplink.c b/src/server/uplink.c
index b6f7887..0a60ff1 100644
--- a/src/server/uplink.c
+++ b/src/server/uplink.c
@@ -66,7 +66,7 @@ int uplink_init(dnbd3_image_t *image, int sock, dnbd3_host_t *host)
link->recvBufferLen = 0;
link->shutdown = FALSE;
spin_init( &link->queueLock, PTHREAD_PROCESS_PRIVATE );
- if ( 0 != pthread_create( &(link->thread), NULL, &uplink_mainloop, (void *)(uintptr_t)link ) ) {
+ if ( 0 != thread_create( &(link->thread), NULL, &uplink_mainloop, (void *)(uintptr_t)link ) ) {
memlogf( "[ERROR] Could not start thread for new client." );
goto failure;
}
@@ -81,6 +81,9 @@ int uplink_init(dnbd3_image_t *image, int sock, dnbd3_host_t *host)
/**
* Locks on image.lock, uplink.lock
+ * Sets image->uplink to NULL while locked, so
+ * calling it multiple times, even concurrently, will
+ * not break anything.
*/
void uplink_shutdown(dnbd3_image_t *image)
{
@@ -99,12 +102,12 @@ void uplink_shutdown(dnbd3_image_t *image)
}
image->uplink = NULL;
uplink->shutdown = TRUE;
+ static uint64_t counter = 1;
+ if ( uplink->signal != -1 ) write( uplink->signal, &counter, sizeof(counter) );
+ pthread_t thread = uplink->thread;
spin_unlock( &uplink->queueLock );
spin_unlock( &image->lock );
- if ( uplink->signal != -1 ) write( uplink->signal, "", 1 );
- if ( uplink->image != NULL ) {
- pthread_join( uplink->thread, NULL );
- }
+ thread_join( thread, NULL );
}
/**
@@ -191,7 +194,7 @@ int uplink_request(dnbd3_client_t *client, uint64_t handle, uint64_t start, uint
if ( foundExisting == -1 ) { // Only wake up uplink thread if the request needs to be relayed
static uint64_t counter = 1;
- write( signalFd, &counter, sizeof(uint64_t) );
+ write( signalFd, &counter, sizeof(counter) );
}
return TRUE;
}
@@ -343,13 +346,6 @@ static void* uplink_mainloop(void *data)
memlogf( "[INFO] Replication of %s complete.", link->image->lower_name );
if ( spin_trylock( &link->image->lock ) == 0 ) {
image_markComplete( link->image );
- spin_lock( &link->queueLock );
- if ( !link->shutdown ) {
- link->image->uplink = NULL;
- link->shutdown = TRUE;
- pthread_detach( link->thread );
- }
- spin_unlock( &link->queueLock );
spin_unlock( &link->image->lock );
goto cleanup;
}
@@ -383,7 +379,7 @@ static void* uplink_mainloop(void *data)
if ( link->queue[i].status != ULR_FREE && link->queue[i].entered < deadline ) {
snprintf( buffer, sizeof(buffer), "[DEBUG WARNING] Starving request detected:\n"
"%s\n(from %" PRIu64 " to %" PRIu64 ", status: %d)\n", link->queue[i].client->image->lower_name,
- link->queue[i].from, link->queue[i].to, link->queue[i].status );
+ link->queue[i].from, link->queue[i].to, link->queue[i].status );
link->queue[i].status = ULR_NEW;
spin_unlock( &link->queueLock );
printf("%s", buffer);
@@ -395,14 +391,19 @@ static void* uplink_mainloop(void *data)
#endif
}
cleanup: ;
+ altservers_removeUplink( link );
spin_lock( &link->image->lock );
spin_lock( &link->queueLock );
- if (link->image != NULL) link->image->uplink = NULL;
- spin_unlock( &link->image->lock );
+ link->image->uplink = NULL;
const int fd = link->fd;
const int signal = link->signal;
link->fd = -1;
link->signal = -1;
+ if ( !link->shutdown ) {
+ link->shutdown = TRUE;
+ thread_detach( link->thread );
+ }
+ spin_unlock( &link->image->lock );
spin_unlock( &link->queueLock );
if ( fd != -1 ) close( fd );
if ( signal != -1 ) close( signal );
@@ -517,7 +518,7 @@ static void uplink_handle_receive(dnbd3_connection_t *link)
if ( ret != sizeof inReply ) {
const int err = errno;
memlogf( "[INFO] Lost connection to uplink server for %s (header %d/%d, e=%d)", link->image->path, ret, (int)sizeof(inReply),
- err );
+ err );
goto error_cleanup;
}
fixup_reply( inReply );