+/**\r
+ Remove the completed tasks from Instance->TaskQueue. Completed tasks are those who don't have any subtasks.\r
+\r
+ @param Instance Pointer to the DISK_IO_PRIVATE_DATA.\r
+\r
+ @retval TRUE The Instance->TaskQueue is empty after the completed tasks are removed.\r
+ @retval FALSE The Instance->TaskQueue is not empty after the completed tasks are removed.\r
+**/\r
+BOOLEAN\r
+DiskIo2RemoveCompletedTask (\r
+ IN DISK_IO_PRIVATE_DATA *Instance\r
+ )\r
+{\r
+ BOOLEAN QueueEmpty;\r
+ LIST_ENTRY *Link;\r
+ DISK_IO2_TASK *Task;\r
+\r
+ QueueEmpty = TRUE;\r
+\r
+ EfiAcquireLock (&Instance->TaskQueueLock);\r
+ for (Link = GetFirstNode (&Instance->TaskQueue); !IsNull (&Instance->TaskQueue, Link); ) {\r
+ Task = CR (Link, DISK_IO2_TASK, Link, DISK_IO2_TASK_SIGNATURE);\r
+ if (IsListEmpty (&Task->Subtasks)) {\r
+ Link = RemoveEntryList (&Task->Link);\r
+ ASSERT (Task->Token == NULL);\r
+ FreePool (Task);\r
+ } else {\r
+ Link = GetNextNode (&Instance->TaskQueue, Link);\r
+ QueueEmpty = FALSE;\r
+ }\r
+ }\r
+ EfiReleaseLock (&Instance->TaskQueueLock);\r
+\r
+ return QueueEmpty;\r
+}\r
+\r