Rework fcore locking

- move lock and unlock to tus_file.c
- clear the fcore pointer argument when the lock is not acquired
parent 12e95a6e
...@@ -483,6 +483,40 @@ tus_file_fini(struct tus_file_core *fcore) ...@@ -483,6 +483,40 @@ tus_file_fini(struct tus_file_core *fcore)
REPLACE(fcore->filename, NULL); REPLACE(fcore->filename, NULL);
FREE_OBJ(fcore); FREE_OBJ(fcore);
} }
/* try to lock the file, loosing the pointer to it if it failes */
int
tus_file_trylock(struct tus_file_core **fcorep)
{
int err = EINVAL;
struct tus_file_core *fcore;
AN(fcorep);
fcore = *fcorep;
if (fcore == NULL)
return (err);
CHECK_OBJ(fcore, VMOD_TUS_FILE_CORE_MAGIC);
do {
err = pthread_mutex_trylock(&fcore->mtx);
if (err == 0)
return (err);
} while (err == EINTR);
*fcorep = NULL;
return (err);
}
/* keep a reference across requests, but done with it for this request */
void
tus_file_unlock(struct tus_file_core **fcorep)
{
struct tus_file_core *fcore;
TAKE_OBJ_NOTNULL(fcore, fcorep, VMOD_TUS_FILE_CORE_MAGIC);
AZ(pthread_mutex_unlock(&fcore->mtx));
}
/* under tus_server mtx to protect tus_files */ /* under tus_server mtx to protect tus_files */
void void
tus_file_del(struct tus_file_core **fcorep) tus_file_del(struct tus_file_core **fcorep)
......
...@@ -137,6 +137,8 @@ VSPLAY_PROTOTYPE(tus_files, tus_file_core, entry, tus_file_cmp) ...@@ -137,6 +137,8 @@ VSPLAY_PROTOTYPE(tus_files, tus_file_core, entry, tus_file_cmp)
void tus_file_init(void); void tus_file_init(void);
void tus_file_load(struct VPFX(tus_server) *); void tus_file_load(struct VPFX(tus_server) *);
void tus_file_shutdown(struct VPFX(tus_server) *srv); void tus_file_shutdown(struct VPFX(tus_server) *srv);
int tus_file_trylock(struct tus_file_core **);
void tus_file_unlock(struct tus_file_core **);
void tus_file_del(struct tus_file_core **); void tus_file_del(struct tus_file_core **);
struct tus_file_core *tus_file_new(VRT_CTX, struct VPFX(tus_server) *, struct tus_file_core *tus_file_new(VRT_CTX, struct VPFX(tus_server) *,
enum tus_f_type, const char *, const char *, const char *); enum tus_f_type, const char *, const char *, const char *);
......
...@@ -246,7 +246,7 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -246,7 +246,7 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
struct concat_embryo embryo; struct concat_embryo embryo;
char *q; char *q;
enum met_e m; enum met_e m;
int ct_ok, lock = EINVAL; int ct_ok, lock;
uintmax_t cl, off = UINTMAX_MAX, len = UINTMAX_MAX; uintmax_t cl, off = UINTMAX_MAX, len = UINTMAX_MAX;
enum tus_f_type type = TUS_SINGLE; enum tus_f_type type = TUS_SINGLE;
struct tus_concat *c; struct tus_concat *c;
...@@ -326,24 +326,22 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -326,24 +326,22 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
if (fcore != NULL) if (fcore != NULL)
r->schemeauth = WS_Copy(ctx->ws, tussrv->schemeauth, -1); r->schemeauth = WS_Copy(ctx->ws, tussrv->schemeauth, -1);
if (fcore != NULL) lock = tus_file_trylock(&fcore);
lock = pthread_mutex_trylock(&fcore->mtx);
AZ(pthread_mutex_unlock(&tussrv->mtx)); AZ(pthread_mutex_unlock(&tussrv->mtx));
if (lock == EBUSY) {
AZ(fcore);
r->status = 423;
return (0);
}
if (fcore != NULL) { if (fcore != NULL) {
assert(lock == 0);
fdisk = fcore->disk; fdisk = fcore->disk;
AN(fdisk); AN(fdisk);
type = fdisk->type; type = fdisk->type;
}
// https://github.com/tus/tus-resumable-upload-protocol/issues/146
if (fcore == NULL) {
assert (lock == EINVAL);
} else if (lock == EBUSY) {
r->status = 423;
return (0);
} else { } else {
assert (lock == 0); assert(lock == EINVAL);
} }
// from here on, we hold a lock on fcore (if != NULL), which we either // from here on, we hold a lock on fcore (if != NULL), which we either
...@@ -363,14 +361,14 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -363,14 +361,14 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
if (m == DELETE) { if (m == DELETE) {
if (fcore == NULL) { if (fcore == NULL) {
r->status = 404; r->status = 404;
} else { return (0);
AZ(pthread_mutex_lock(&tussrv->mtx));
tus_file_del(&fcore);
// unlocks fcore
AZ(pthread_mutex_unlock(&tussrv->mtx));
r->status = 204;
} }
return (0);
AZ(pthread_mutex_lock(&tussrv->mtx));
tus_file_del(&fcore);
AZ(pthread_mutex_unlock(&tussrv->mtx));
AZ(fcore);
r->status = 204;
} }
AZ(r->fcore); AZ(r->fcore);
...@@ -382,12 +380,13 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -382,12 +380,13 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
AN(fcore); AN(fcore);
AN(fdisk); AN(fdisk);
if (fdisk->location_length > 0) { if (fdisk->location_length > 0) {
r->fcore = fcore;
r->status = 301; /* done file */ r->status = 301; /* done file */
} else { } else {
AZ(pthread_mutex_unlock(&fcore->mtx)); tus_file_unlock(&fcore);
AZ(fcore);
r->status = 400; r->status = 400;
} }
r->fcore = fcore;
return (0); return (0);
} }
......
...@@ -312,8 +312,8 @@ tus_task_free(VRT_CTX, void *ptr) ...@@ -312,8 +312,8 @@ tus_task_free(VRT_CTX, void *ptr)
CAST_OBJ_NOTNULL(r, ptr, VMOD_TUS_RESPONSE_MAGIC); CAST_OBJ_NOTNULL(r, ptr, VMOD_TUS_RESPONSE_MAGIC);
if (r->fcore == NULL) if (r->fcore == NULL)
return; return;
AZ(pthread_mutex_unlock(&r->fcore->mtx)); tus_file_unlock(&r->fcore);
r->fcore = NULL; AZ(r->fcore);
} }
static const struct vmod_priv_methods priv_task_methods[1] = {{ static const struct vmod_priv_methods priv_task_methods[1] = {{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment