Fix remaining use of mutexes lock/unlocking in different threads with cksems, corecting cksem usage on osx

This commit is contained in:
ckolivas 2015-03-08 10:10:38 +11:00
parent dd9dc7555d
commit f690750340
5 changed files with 32 additions and 36 deletions

View file

@ -30,6 +30,7 @@
#include <stdio.h> #include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <stdarg.h> #include <stdarg.h>
#include <semaphore.h>
#ifdef HAVE_PTHREAD_H #ifdef HAVE_PTHREAD_H
# include <pthread.h> # include <pthread.h>
@ -149,6 +150,18 @@ typedef uint32_t u32;
typedef struct rzip_control rzip_control; typedef struct rzip_control rzip_control;
typedef struct md5_ctx md5_ctx; typedef struct md5_ctx md5_ctx;
/* ck specific unnamed semaphore implementations to cope with osx not
* implementing them. */
#ifdef __APPLE__
struct cksem {
int pipefd[2];
};
typedef struct cksem cksem_t;
#else
typedef sem_t cksem_t;
#endif
#if !defined(__linux) #if !defined(__linux)
#define mremap fake_mremap #define mremap fake_mremap
#endif #endif
@ -409,7 +422,7 @@ struct rzip_control {
unsigned char magic_written; unsigned char magic_written;
bool lzma_prop_set; bool lzma_prop_set;
pthread_mutex_t cksumlock; cksem_t cksumsem;
md5_ctx ctx; md5_ctx ctx;
uchar md5_resblock[MD5_DIGEST_SIZE]; uchar md5_resblock[MD5_DIGEST_SIZE];
i64 md5_read; // How far into the file the md5 has done so far i64 md5_read; // How far into the file the md5 has done so far

17
rzip.c
View file

@ -607,7 +607,7 @@ static void *cksumthread(void *data)
if (!NO_MD5) if (!NO_MD5)
md5_process_bytes(control->checksum.buf, control->checksum.len, &control->ctx); md5_process_bytes(control->checksum.buf, control->checksum.len, &control->ctx);
free(control->checksum.buf); free(control->checksum.buf);
unlock_mutex(control, &control->cksumlock); cksem_post(control, &control->cksumsem);
return NULL; return NULL;
} }
@ -738,7 +738,7 @@ static inline bool hash_search(rzip_control *control, struct rzip_state *st,
* cksumthread. This lock protects all the data in * cksumthread. This lock protects all the data in
* control->checksum. * control->checksum.
*/ */
lock_mutex(control, &control->cksumlock); cksem_wait(control, &control->cksumsem);
control->checksum.len = MIN(st->chunk_size - p, control->page_size); control->checksum.len = MIN(st->chunk_size - p, control->page_size);
control->checksum.buf = malloc(control->checksum.len); control->checksum.buf = malloc(control->checksum.len);
if (unlikely(!control->checksum.buf)) if (unlikely(!control->checksum.buf))
@ -759,7 +759,7 @@ static inline bool hash_search(rzip_control *control, struct rzip_state *st,
if (st->chunk_size > cksum_limit) { if (st->chunk_size > cksum_limit) {
/* Compute checksum. If the entire chunk is longer than maxram, /* Compute checksum. If the entire chunk is longer than maxram,
* do it "per-partes" */ * do it "per-partes" */
lock_mutex(control, &control->cksumlock); cksem_wait(control, &control->cksumsem);
control->checksum.len = st->chunk_size - cksum_limit; control->checksum.len = st->chunk_size - cksum_limit;
cksum_chunks = control->checksum.len / control->maxram; cksum_chunks = control->checksum.len / control->maxram;
cksum_remains = control->checksum.len % control->maxram; cksum_remains = control->checksum.len % control->maxram;
@ -781,9 +781,11 @@ static inline bool hash_search(rzip_control *control, struct rzip_state *st,
if (!NO_MD5) if (!NO_MD5)
md5_process_bytes(control->checksum.buf, cksum_remains, &control->ctx); md5_process_bytes(control->checksum.buf, cksum_remains, &control->ctx);
free(control->checksum.buf); free(control->checksum.buf);
unlock_mutex(control, &control->cksumlock); cksem_post(control, &control->cksumsem);
} else } else {
wait_mutex(control, &control->cksumlock); cksem_wait(control, &control->cksumsem);
cksem_post(control, &control->cksumsem);
}
if (unlikely(!put_literal(control, st, 0, 0))) if (unlikely(!put_literal(control, st, 0, 0)))
return false; return false;
@ -954,7 +956,8 @@ bool rzip_fd(rzip_control *control, int fd_in, int fd_out)
init_mutex(control, &control->control_lock); init_mutex(control, &control->control_lock);
if (!NO_MD5) if (!NO_MD5)
md5_init_ctx(&control->ctx); md5_init_ctx(&control->ctx);
init_mutex(control, &control->cksumlock); cksem_init(control, &control->cksumsem);
cksem_post(control, &control->cksumsem);
st = calloc(sizeof(*st), 1); st = calloc(sizeof(*st), 1);
if (unlikely(!st)) if (unlikely(!st))

View file

@ -113,17 +113,6 @@ bool lock_mutex(rzip_control *control, pthread_mutex_t *mutex)
return true; return true;
} }
/* Lock and unlock a mutex */
bool wait_mutex(rzip_control *control, pthread_mutex_t *mutex)
{
bool ret;
ret = lock_mutex(control, mutex);
if (likely(ret))
ret = unlock_mutex(control, mutex);
return ret;
}
static bool cond_wait(rzip_control *control, pthread_cond_t *cond, pthread_mutex_t *mutex) static bool cond_wait(rzip_control *control, pthread_cond_t *cond, pthread_mutex_t *mutex)
{ {
if (unlikely(pthread_cond_wait(cond, mutex))) if (unlikely(pthread_cond_wait(cond, mutex)))

View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2006-2011 Con Kolivas Copyright (C) 2006-2015 Con Kolivas
Copyright (C) 2011 Peter Hyman Copyright (C) 2011 Peter Hyman
Copyright (C) 1998-2003 Andrew Tridgell Copyright (C) 1998-2003 Andrew Tridgell
@ -29,7 +29,6 @@ bool join_pthread(pthread_t th, void **thread_return);
bool init_mutex(rzip_control *control, pthread_mutex_t *mutex); bool init_mutex(rzip_control *control, pthread_mutex_t *mutex);
bool unlock_mutex(rzip_control *control, pthread_mutex_t *mutex); bool unlock_mutex(rzip_control *control, pthread_mutex_t *mutex);
bool lock_mutex(rzip_control *control, pthread_mutex_t *mutex); bool lock_mutex(rzip_control *control, pthread_mutex_t *mutex);
bool wait_mutex(rzip_control *control, pthread_mutex_t *mutex);
ssize_t write_1g(rzip_control *control, void *buf, i64 len); ssize_t write_1g(rzip_control *control, void *buf, i64 len);
ssize_t read_1g(rzip_control *control, int fd, void *buf, i64 len); ssize_t read_1g(rzip_control *control, int fd, void *buf, i64 len);
i64 get_readseek(rzip_control *control, int fd); i64 get_readseek(rzip_control *control, int fd);

22
util.h
View file

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2006-2011 Con Kolivas Copyright (C) 2006-2015 Con Kolivas
Copyright (C) 2011 Peter Hyman Copyright (C) 2011 Peter Hyman
Copyright (C) 1998 Andrew Tridgell Copyright (C) 1998 Andrew Tridgell
@ -23,6 +23,8 @@
#include <errno.h> #include <errno.h>
#include <semaphore.h> #include <semaphore.h>
#include <stdarg.h> #include <stdarg.h>
#include <unistd.h>
#include <fcntl.h>
void register_infile(rzip_control *control, const char *name, char delete); void register_infile(rzip_control *control, const char *name, char delete);
void register_outfile(rzip_control *control, const char *name, char delete); void register_outfile(rzip_control *control, const char *name, char delete);
@ -104,18 +106,6 @@ static inline bool lrz_decrypt(const rzip_control *control, uchar *buf, i64 len,
return lrz_crypt(control, buf, len, salt, LRZ_DECRYPT); return lrz_crypt(control, buf, len, salt, LRZ_DECRYPT);
} }
/* ck specific unnamed semaphore implementations to cope with osx not
* implementing them. */
#ifdef __APPLE__
struct cksem {
int pipefd[2];
};
typedef struct cksem cksem_t;
#else
typedef sem_t cksem_t;
#endif
/* ck specific wrappers for true unnamed semaphore usage on platforms /* ck specific wrappers for true unnamed semaphore usage on platforms
* that support them and for apple which does not. We use a single byte across * that support them and for apple which does not. We use a single byte across
* a pipe to emulate semaphore behaviour there. */ * a pipe to emulate semaphore behaviour there. */
@ -145,7 +135,7 @@ static inline void cksem_post(const rzip_control *control, cksem_t *cksem)
ret = write(cksem->pipefd[1], &buf, 1); ret = write(cksem->pipefd[1], &buf, 1);
if (unlikely(ret == 0)) if (unlikely(ret == 0))
fatal("Failed to write errno=%d" IN_FMT_FFL, errno, file, func, line); fatal("Failed to write in cksem_post errno=%d", errno);
} }
static inline void cksem_wait(const rzip_control *control, cksem_t *cksem) static inline void cksem_wait(const rzip_control *control, cksem_t *cksem)
@ -155,7 +145,7 @@ static inline void cksem_wait(const rzip_control *control, cksem_t *cksem)
ret = read(cksem->pipefd[0], &buf, 1); ret = read(cksem->pipefd[0], &buf, 1);
if (unlikely(ret == 0)) if (unlikely(ret == 0))
fatal("Failed to read errno=%d" IN_FMT_FFL, errno, file, func, line); fatal("Failed to read in cksem_post errno=%d", errno);
} }
static inline void cksem_destroy(cksem_t *cksem) static inline void cksem_destroy(cksem_t *cksem)
@ -178,6 +168,8 @@ static inline void cksem_reset(const rzip_control *control, cksem_t *cksem)
struct timeval timeout = {0, 0}; struct timeval timeout = {0, 0};
ret = select(fd + 1, &rd, NULL, NULL, &timeout); ret = select(fd + 1, &rd, NULL, NULL, &timeout);
if (unlikely(ret == -1))
fatal("Error in select in cksem_reset errno=%d", errno);
if (ret > 0) if (ret > 0)
ret = read(fd, &buf, 1); ret = read(fd, &buf, 1);
} while (ret > 0); } while (ret > 0);