diff --git a/src/Common/EncryptionThreadPool.c b/src/Common/EncryptionThreadPool.c index 6124497d..50e33c7f 100644 --- a/src/Common/EncryptionThreadPool.c +++ b/src/Common/EncryptionThreadPool.c @@ -192,6 +192,7 @@ static void SetWorkItemState (EncryptionThreadPoolWorkItem *workItem, WorkItemSt static TC_THREAD_PROC EncryptionThreadProc (void *threadArg) { EncryptionThreadPoolWorkItem *workItem; + EncryptionThreadPoolWorkItem *firstFragment; if (threadArg) { #ifdef DEVICE_DRIVER @@ -333,14 +334,16 @@ static TC_THREAD_PROC EncryptionThreadProc (void *threadArg) TC_THROW_FATAL_EXCEPTION; } - if (workItem != workItem->FirstFragment) + // Keep the parent reference before releasing this queue slot. + firstFragment = workItem->FirstFragment; + if (workItem != firstFragment) { SetWorkItemState (workItem, WorkItemFree); TC_SET_EVENT (WorkItemCompletedEvent); } - if (InterlockedDecrement (&workItem->FirstFragment->OutstandingFragmentCount) == 0) - TC_SET_EVENT (workItem->FirstFragment->ItemCompletedEvent); + if (InterlockedDecrement (&firstFragment->OutstandingFragmentCount) == 0) + TC_SET_EVENT (firstFragment->ItemCompletedEvent); } #ifdef DEVICE_DRIVER diff --git a/src/Volume/EncryptionThreadPool.cpp b/src/Volume/EncryptionThreadPool.cpp index a7f4a4ce..0b37df0f 100644 --- a/src/Volume/EncryptionThreadPool.cpp +++ b/src/Volume/EncryptionThreadPool.cpp @@ -375,14 +375,16 @@ namespace VeraCrypt continue; } - if (workItem != workItem->FirstFragment) + // Keep the parent reference before releasing this queue slot. + WorkItem *firstFragment = workItem->FirstFragment; + if (workItem != firstFragment) { workItem->State.Set (WorkItem::State::Free); WorkItemCompletedEvent.Signal(); } - if (workItem->FirstFragment->OutstandingFragmentCount.Decrement() == 0) - workItem->FirstFragment->ItemCompletedEvent.Signal(); + if (firstFragment->OutstandingFragmentCount.Decrement() == 0) + firstFragment->ItemCompletedEvent.Signal(); } } catch (exception &e)