diff options
Diffstat (limited to 'apps')
-rw-r--r-- | apps/buffering.c | 45 |
1 files changed, 27 insertions, 18 deletions
diff --git a/apps/buffering.c b/apps/buffering.c index 79262a2f13..72b3890ef0 100644 --- a/apps/buffering.c +++ b/apps/buffering.c | |||
@@ -82,13 +82,13 @@ enum handle_flags | |||
82 | 82 | ||
83 | struct memory_handle { | 83 | struct memory_handle { |
84 | struct lld_node hnode; /* Handle list node (first!) */ | 84 | struct lld_node hnode; /* Handle list node (first!) */ |
85 | struct lld_node mrunode;/* MRU list node */ | 85 | struct lld_node mrunode;/* MRU list node (second!) */ |
86 | int id; /* A unique ID for the handle (after list!) */ | 86 | size_t size; /* Size of this structure + its auxilliary data */ |
87 | int id; /* A unique ID for the handle */ | ||
87 | enum data_type type; /* Type of data buffered with this handle */ | 88 | enum data_type type; /* Type of data buffered with this handle */ |
88 | uint8_t flags; /* Handle property flags */ | 89 | uint8_t flags; /* Handle property flags */ |
89 | int8_t pinned; /* Count of pinnings */ | 90 | int8_t pinned; /* Count of pinnings */ |
90 | int8_t signaled; /* Stop any attempt at waiting to get the data */ | 91 | int8_t signaled; /* Stop any attempt at waiting to get the data */ |
91 | char path[MAX_PATH]; /* Path if data originated in a file */ | ||
92 | int fd; /* File descriptor to path (-1 if closed) */ | 92 | int fd; /* File descriptor to path (-1 if closed) */ |
93 | size_t data; /* Start index of the handle's data buffer */ | 93 | size_t data; /* Start index of the handle's data buffer */ |
94 | size_t ridx; /* Read pointer, relative to the main buffer */ | 94 | size_t ridx; /* Read pointer, relative to the main buffer */ |
@@ -97,8 +97,12 @@ struct memory_handle { | |||
97 | off_t start; /* Offset at which we started reading the file */ | 97 | off_t start; /* Offset at which we started reading the file */ |
98 | off_t pos; /* Read position in file */ | 98 | off_t pos; /* Read position in file */ |
99 | off_t volatile end; /* Offset at which we stopped reading the file */ | 99 | off_t volatile end; /* Offset at which we stopped reading the file */ |
100 | char path[]; /* Path if data originated in a file */ | ||
100 | }; | 101 | }; |
101 | 102 | ||
103 | /* Minimum allowed handle movement */ | ||
104 | #define MIN_MOVE_DELTA sizeof(struct memory_handle) | ||
105 | |||
102 | struct buf_message_data | 106 | struct buf_message_data |
103 | { | 107 | { |
104 | int handle_id; | 108 | int handle_id; |
@@ -344,7 +348,8 @@ static void adjust_handle_node(struct lld_head *list, | |||
344 | NULL if there memory_handle itself cannot be allocated or if the | 348 | NULL if there memory_handle itself cannot be allocated or if the |
345 | data_size cannot be allocated and alloc_all is set. */ | 349 | data_size cannot be allocated and alloc_all is set. */ |
346 | static struct memory_handle * | 350 | static struct memory_handle * |
347 | add_handle(unsigned int flags, size_t data_size, size_t *data_out) | 351 | add_handle(unsigned int flags, size_t data_size, const char *path, |
352 | size_t *data_out) | ||
348 | { | 353 | { |
349 | /* Gives each handle a unique id */ | 354 | /* Gives each handle a unique id */ |
350 | if (num_handles >= BUF_MAX_HANDLES) | 355 | if (num_handles >= BUF_MAX_HANDLES) |
@@ -376,14 +381,17 @@ add_handle(unsigned int flags, size_t data_size, size_t *data_out) | |||
376 | } | 381 | } |
377 | 382 | ||
378 | /* Align to align size up */ | 383 | /* Align to align size up */ |
384 | size_t pathsize = path ? strlen(path) + 1 : 0; | ||
379 | size_t adjust = ALIGN_UP(widx, alignof(struct memory_handle)) - widx; | 385 | size_t adjust = ALIGN_UP(widx, alignof(struct memory_handle)) - widx; |
380 | size_t index = ringbuf_add(widx, adjust); | 386 | size_t index = ringbuf_add(widx, adjust); |
381 | size_t len = data_size + sizeof(struct memory_handle); | 387 | size_t handlesize = ALIGN_UP(sizeof(struct memory_handle) + pathsize, |
388 | alignof(struct memory_handle)); | ||
389 | size_t len = handlesize + data_size; | ||
382 | 390 | ||
383 | /* First, will the handle wrap? */ | 391 | /* First, will the handle wrap? */ |
384 | /* If the handle would wrap, move to the beginning of the buffer, | 392 | /* If the handle would wrap, move to the beginning of the buffer, |
385 | * or if the data must not but would wrap, move it to the beginning */ | 393 | * or if the data must not but would wrap, move it to the beginning */ |
386 | if (index + sizeof(struct memory_handle) > buffer_len || | 394 | if (index + handlesize > buffer_len || |
387 | (!(flags & H_CANWRAP) && index + len > buffer_len)) { | 395 | (!(flags & H_CANWRAP) && index + len > buffer_len)) { |
388 | index = 0; | 396 | index = 0; |
389 | } | 397 | } |
@@ -405,13 +413,17 @@ add_handle(unsigned int flags, size_t data_size, size_t *data_out) | |||
405 | /* There is enough space for the required data, initialize the struct */ | 413 | /* There is enough space for the required data, initialize the struct */ |
406 | struct memory_handle *h = ringbuf_ptr(index); | 414 | struct memory_handle *h = ringbuf_ptr(index); |
407 | 415 | ||
416 | h->size = handlesize; | ||
408 | h->id = next_handle_id(); | 417 | h->id = next_handle_id(); |
409 | h->flags = flags; | 418 | h->flags = flags; |
410 | h->pinned = 0; /* Can be moved */ | 419 | h->pinned = 0; /* Can be moved */ |
411 | h->signaled = 0; /* Data can be waited for */ | 420 | h->signaled = 0; /* Data can be waited for */ |
412 | 421 | ||
422 | /* Save the provided path */ | ||
423 | memcpy(h->path, path, pathsize); | ||
424 | |||
413 | /* Return the start of the data area */ | 425 | /* Return the start of the data area */ |
414 | *data_out = ringbuf_add(index, sizeof (struct memory_handle)); | 426 | *data_out = ringbuf_add(index, handlesize); |
415 | 427 | ||
416 | return h; | 428 | return h; |
417 | } | 429 | } |
@@ -457,13 +469,13 @@ static bool move_handle(struct memory_handle **h, size_t *delta, | |||
457 | if (h == NULL || (src = *h) == NULL) | 469 | if (h == NULL || (src = *h) == NULL) |
458 | return false; | 470 | return false; |
459 | 471 | ||
460 | size_t size_to_move = sizeof(struct memory_handle) + data_size; | 472 | size_t size_to_move = src->size + data_size; |
461 | 473 | ||
462 | /* Align to align size down */ | 474 | /* Align to align size down */ |
463 | size_t final_delta = *delta; | 475 | size_t final_delta = *delta; |
464 | final_delta = ALIGN_DOWN(final_delta, alignof(struct memory_handle)); | 476 | final_delta = ALIGN_DOWN(final_delta, alignof(struct memory_handle)); |
465 | if (final_delta < sizeof(struct memory_handle)) { | 477 | if (final_delta < MIN_MOVE_DELTA) { |
466 | /* It's not legal to move less than the size of the struct */ | 478 | /* It's not legal to move less than MIN_MOVE_DELTA */ |
467 | return false; | 479 | return false; |
468 | } | 480 | } |
469 | 481 | ||
@@ -490,8 +502,8 @@ static bool move_handle(struct memory_handle **h, size_t *delta, | |||
490 | if (correction) { | 502 | if (correction) { |
491 | /* Align correction to align size up */ | 503 | /* Align correction to align size up */ |
492 | correction = ALIGN_UP(correction, alignof(struct memory_handle)); | 504 | correction = ALIGN_UP(correction, alignof(struct memory_handle)); |
493 | if (final_delta < correction + sizeof(struct memory_handle)) { | 505 | if (final_delta < correction + MIN_MOVE_DELTA) { |
494 | /* Delta cannot end up less than the size of the struct */ | 506 | /* Delta cannot end up less than MIN_MOVE_DELTA */ |
495 | return false; | 507 | return false; |
496 | } | 508 | } |
497 | newpos -= correction; | 509 | newpos -= correction; |
@@ -918,13 +930,12 @@ int bufopen(const char *file, size_t offset, enum data_type type, | |||
918 | /* ID3 case: allocate space, init the handle and return. */ | 930 | /* ID3 case: allocate space, init the handle and return. */ |
919 | mutex_lock(&llist_mutex); | 931 | mutex_lock(&llist_mutex); |
920 | 932 | ||
921 | h = add_handle(H_ALLOCALL, sizeof(struct mp3entry), &data); | 933 | h = add_handle(H_ALLOCALL, sizeof(struct mp3entry), file, &data); |
922 | 934 | ||
923 | if (h) { | 935 | if (h) { |
924 | handle_id = h->id; | 936 | handle_id = h->id; |
925 | 937 | ||
926 | h->type = type; | 938 | h->type = type; |
927 | strlcpy(h->path, file, MAX_PATH); | ||
928 | h->fd = -1; | 939 | h->fd = -1; |
929 | h->data = data; | 940 | h->data = data; |
930 | h->ridx = data; | 941 | h->ridx = data; |
@@ -983,7 +994,7 @@ int bufopen(const char *file, size_t offset, enum data_type type, | |||
983 | 994 | ||
984 | mutex_lock(&llist_mutex); | 995 | mutex_lock(&llist_mutex); |
985 | 996 | ||
986 | h = add_handle(hflags, padded_size, &data); | 997 | h = add_handle(hflags, padded_size, file, &data); |
987 | if (!h) { | 998 | if (!h) { |
988 | DEBUGF("%s(): failed to add handle\n", __func__); | 999 | DEBUGF("%s(): failed to add handle\n", __func__); |
989 | mutex_unlock(&llist_mutex); | 1000 | mutex_unlock(&llist_mutex); |
@@ -994,7 +1005,6 @@ int bufopen(const char *file, size_t offset, enum data_type type, | |||
994 | handle_id = h->id; | 1005 | handle_id = h->id; |
995 | 1006 | ||
996 | h->type = type; | 1007 | h->type = type; |
997 | strlcpy(h->path, file, MAX_PATH); | ||
998 | h->fd = -1; | 1008 | h->fd = -1; |
999 | 1009 | ||
1000 | #ifdef STORAGE_WANTS_ALIGN | 1010 | #ifdef STORAGE_WANTS_ALIGN |
@@ -1080,7 +1090,7 @@ int bufalloc(const void *src, size_t size, enum data_type type) | |||
1080 | mutex_lock(&llist_mutex); | 1090 | mutex_lock(&llist_mutex); |
1081 | 1091 | ||
1082 | size_t data; | 1092 | size_t data; |
1083 | struct memory_handle *h = add_handle(H_ALLOCALL, size, &data); | 1093 | struct memory_handle *h = add_handle(H_ALLOCALL, size, NULL, &data); |
1084 | 1094 | ||
1085 | if (h) { | 1095 | if (h) { |
1086 | handle_id = h->id; | 1096 | handle_id = h->id; |
@@ -1095,7 +1105,6 @@ int bufalloc(const void *src, size_t size, enum data_type type) | |||
1095 | } | 1105 | } |
1096 | 1106 | ||
1097 | h->type = type; | 1107 | h->type = type; |
1098 | h->path[0] = '\0'; | ||
1099 | h->fd = -1; | 1108 | h->fd = -1; |
1100 | h->data = data; | 1109 | h->data = data; |
1101 | h->ridx = data; | 1110 | h->ridx = data; |