Simplify: Only one fcore reference in tus_request()

Keeping a local varaible and the struct response member with a pointer to
the fcore was unnecessary complex and a possible cause for error.

Now that holding a pointer is conceptually equal to holding a lock,
we should really avoid the local variable.

Also fixes an (unlikely) leaked lock for TUS_FINAL and method != POST
parent a7243a24
...@@ -240,7 +240,6 @@ VCL_BOOL ...@@ -240,7 +240,6 @@ VCL_BOOL
tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
struct tus_response *r, const char *url, const char *id) struct tus_response *r, const char *url, const char *id)
{ {
struct tus_file_core *fcore;
struct tus_file_disk *fdisk = NULL; struct tus_file_disk *fdisk = NULL;
const char *p, *metadata = NULL, *concat = NULL; const char *p, *metadata = NULL, *concat = NULL;
struct concat_embryo embryo; struct concat_embryo embryo;
...@@ -318,92 +317,86 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -318,92 +317,86 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
AZ(pthread_mutex_lock(&tussrv->mtx)); AZ(pthread_mutex_lock(&tussrv->mtx));
if (m == POST) { if (m == POST) {
fcore = tus_file_new(ctx, tussrv, type, url, id, metadata); r->fcore = tus_file_new(ctx, tussrv, type, url, id, metadata);
} else { } else {
fcore = tus_file_lookup(tussrv, url); r->fcore = tus_file_lookup(tussrv, url);
} }
if (fcore != NULL) if (r->fcore != NULL)
r->schemeauth = WS_Copy(ctx->ws, tussrv->schemeauth, -1); r->schemeauth = WS_Copy(ctx->ws, tussrv->schemeauth, -1);
lock = tus_file_trylock(&fcore); lock = tus_file_trylock(&r->fcore);
AZ(pthread_mutex_unlock(&tussrv->mtx)); AZ(pthread_mutex_unlock(&tussrv->mtx));
if (lock == EBUSY) { if (lock == EBUSY) {
AZ(fcore); AZ(r->fcore);
r->status = 423; r->status = 423;
return (0); return (0);
} }
if (fcore != NULL) { if (r->fcore != NULL) {
assert(lock == 0); assert(lock == 0);
fdisk = fcore->disk; fdisk = r->fcore->disk;
AN(fdisk); AN(fdisk);
type = fdisk->type; type = fdisk->type;
} else { } else {
assert(lock == EINVAL); 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 r->fcore (if != NULL), which we either
// need to unlock or pass to the response, which unlocks via // need to unlock or pass to the response, which unlocks via
// tus_task_free() // tus_task_free()
if (m == POST && type == TUS_FINAL) { if (m == POST && type == TUS_FINAL) {
if (fcore == NULL) { if (r->fcore == NULL) {
tus_file_final_abort(&embryo); tus_file_final_abort(&embryo);
} else { } else {
fcore = tus_file_final_birth(fcore, &embryo); r->fcore = tus_file_final_birth(r->fcore, &embryo);
r->status = 201; r->status = 201;
} }
} }
AZ(r->fcore);
if (m == DELETE) { if (m == DELETE) {
if (fcore == NULL) { if (r->fcore == NULL) {
r->status = 404; r->status = 404;
return (0); return (0);
} }
AZ(pthread_mutex_lock(&tussrv->mtx)); AZ(pthread_mutex_lock(&tussrv->mtx));
tus_file_del(&fcore); tus_file_del(&r->fcore);
AZ(pthread_mutex_unlock(&tussrv->mtx)); AZ(pthread_mutex_unlock(&tussrv->mtx));
AZ(fcore); AZ(r->fcore);
r->status = 204; r->status = 204;
} }
AZ(r->fcore);
if (m == GET) { if (m == GET) {
if (fcore == NULL) { if (r->fcore == NULL) {
r->status = 404; r->status = 404;
return (0); return (0);
} }
AN(fcore); AN(r->fcore);
AN(fdisk); AN(fdisk);
if (fdisk->location_length > 0) { if (fdisk->location_length > 0) {
r->status = 301; /* done file */ r->status = 301; /* done file */
} else { } else {
tus_file_unlock(&fcore); tus_file_unlock(&r->fcore);
AZ(fcore); AZ(r->fcore);
r->status = 400; r->status = 400;
} }
r->fcore = fcore;
return (0); return (0);
} }
AZ(r->fcore);
r->fcore = fcore;
if (m == HEAD) { if (m == HEAD) {
r->status = fcore ? 200 : 404; r->status = r->fcore ? 200 : 404;
return (0); return (0);
} }
if (fcore == NULL) { if (r->fcore == NULL) {
r->status = (m == POST) ? 409 : 404; r->status = (m == POST) ? 409 : 404;
return (0); return (0);
} }
AN(fcore); AN(r->fcore);
AN(fdisk); AN(fdisk);
ct_ok = http_GetHdr(ctx->http_req, H_Content_Type, &p) && ct_ok = http_GetHdr(ctx->http_req, H_Content_Type, &p) &&
...@@ -448,10 +441,11 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -448,10 +441,11 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
if (type == TUS_FINAL) { if (type == TUS_FINAL) {
if (m != POST) { if (m != POST) {
r->status = 403; r->status = 403;
r->fcore = NULL; tus_file_unlock(&r->fcore);
AZ(r->fcore);
return (0); return (0);
} }
return (tus_request_complete(ctx, tussrv, fcore->ptr, fdisk)); return (tus_request_complete(ctx, tussrv, r->fcore->ptr, fdisk));
} }
assert (type != TUS_FINAL); assert (type != TUS_FINAL);
...@@ -466,7 +460,7 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -466,7 +460,7 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
r->status = 409; r->status = 409;
return (0); return (0);
} }
r->status = tus_body_to_file(ctx, fcore); r->status = tus_body_to_file(ctx, r->fcore);
break; break;
} }
case POST: { case POST: {
...@@ -487,7 +481,7 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -487,7 +481,7 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
break; break;
} }
r->status = tus_body_to_file(ctx, fcore); r->status = tus_body_to_file(ctx, r->fcore);
if (r->status != 204) if (r->status != 204)
break; break;
r->status = 201; r->status = 201;
...@@ -499,18 +493,18 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv, ...@@ -499,18 +493,18 @@ tus_request(VRT_CTX, struct VPFX(tus_server) *tussrv,
if (r->status == 413) { if (r->status == 413) {
AZ(pthread_mutex_lock(&tussrv->mtx)); AZ(pthread_mutex_lock(&tussrv->mtx));
tus_file_del(&fcore); tus_file_del(&r->fcore);
AZ(pthread_mutex_unlock(&tussrv->mtx)); AZ(pthread_mutex_unlock(&tussrv->mtx));
r->fcore = NULL; AZ(r->fcore);
return (0); return (0);
} }
if (fdisk->upload_offset == fdisk->upload_length) { if (fdisk->upload_offset == fdisk->upload_length) {
tus_file_mmap(fcore); tus_file_mmap(r->fcore);
AZ(pthread_cond_signal(&fcore->cond)); AZ(pthread_cond_signal(&r->fcore->cond));
if (type == TUS_PARTIAL) if (type == TUS_PARTIAL)
return (0); return (0);
assert (type == TUS_SINGLE); assert (type == TUS_SINGLE);
c = tus_body_single(ctx->req, fcore); c = tus_body_single(ctx->req, r->fcore);
if (c == NULL) { if (c == NULL) {
VRT_fail(ctx, "not enough workspace"); VRT_fail(ctx, "not enough workspace");
return (0); return (0);
......
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