Skip to content

Commit

Permalink
Fix Issue 14097 - root/async.c: free after use
Browse files Browse the repository at this point in the history
Also add some docs.
  • Loading branch information
Ketmar Dark authored and PetarKirov committed May 15, 2015
1 parent 63644c0 commit 9bc9da6
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 1 deletion.
17 changes: 16 additions & 1 deletion src/root/async.c
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,15 @@ unsigned __stdcall startthread(void *p)
AsyncRead *aw = (AsyncRead *)p;

//printf("aw->filesdim = %p %d\n", aw, aw->filesdim);
for (size_t i = 0; i < aw->filesdim; i++)

// We need to cache aw->filesdim in order to prevent it from
// being accessed after aw is freed. (It is possible that just
// before the loop finishes the main thread calls
// AsyncRead::dispose() and frees aw before it is accessed
// for the last time.
size_t dim = aw->filesdim;

for (size_t i = 0; i < dim; i++)
{ FileData *f = &aw->files[i];

f->result = f->file->read();
Expand Down Expand Up @@ -243,7 +251,14 @@ void *startthread(void *p)
AsyncRead *aw = (AsyncRead *)p;

//printf("startthread: aw->filesdim = %p %d\n", aw, aw->filesdim);

// We need to cache aw->filesdim in order to prevent it from
// being accessed after aw is freed. (It is possible that just
// before the loop finishes the main thread calls
// AsyncRead::dispose() and frees aw before it is accessed
// for the last time.
size_t dim = aw->filesdim;

for (size_t i = 0; i < dim; i++)
{ FileData *f = &aw->files[i];

Expand Down
15 changes: 15 additions & 0 deletions src/root/async.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,25 @@

struct AsyncRead
{
// Creates a new instance of a AsyncRead. `nfiles` is maximum
// number of files that can be queued for reading.
static AsyncRead *create(size_t nfiles);

// Queues a file for reading. Can only be called before `start()`.
// Only `nfiles` can be added to the queue (`nfiles` is the
// parameter to `create()`).
void addFile(File *file);

// Starts a background thread which reads (asynchronously) all queued files.
void start();

// Blocks the calling thread until the background thread
// finishes reading the i-th file.
int read(size_t i);

// Frees the object returned by `AsyncRead::create()`. It is safe to call
// only after `read()` is called for all queued files, because it doesn't
// wait for the background thread to finish.
static void dispose(AsyncRead *);
};

Expand Down

0 comments on commit 9bc9da6

Please sign in to comment.