1) Fix bug in StatusCodeDxe about the nested DataHub->Log in callback.
2) Close a small window which may result in the data collision of records.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@3641 6f19259b-4bc3-4df7-8a09-765794883524
diff --git a/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c b/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c
index 70f41e9..c14dfc8 100644
--- a/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c
+++ b/IntelFrameworkModulePkg/Universal/StatusCode/Dxe/DataHubStatusCodeWorker.c
@@ -22,6 +22,8 @@
 STATIC

 LIST_ENTRY                mRecordsBuffer        = INITIALIZE_LIST_HEAD_VARIABLE (mRecordsBuffer);

 STATIC

+UINT32                    mLogDataHubStatus     = 0;

+STATIC

 EFI_EVENT                 mLogDataHubEvent;

 //

 // Cache data hub protocol.

@@ -59,6 +61,9 @@
     Record = _CR (Node, DATAHUB_STATUSCODE_RECORD, Node);

   } else {

     if (CurrentTpl > TPL_NOTIFY) {

+      //

+      // Memory management should work at <=TPL_NOTIFY

+      // 

       gBS->RestoreTPL (CurrentTpl);

       return NULL;

     }

@@ -108,10 +113,9 @@
   if (!IsListEmpty (&mRecordsFifo)) {

     Node = GetFirstNode (&mRecordsFifo);

     Record = CR (Node, DATAHUB_STATUSCODE_RECORD, Node, DATAHUB_STATUS_CODE_SIGNATURE);

+    ASSERT (NULL != Record);

 

     RemoveEntryList (&Record->Node);

-    InsertTailList (&mRecordsBuffer, &Record->Node);

-    Record->Signature = 0;

     RecordData = (DATA_HUB_STATUS_CODE_DATA_RECORD *) Record->Data;

   }

 

@@ -120,6 +124,34 @@
   return RecordData;

 }

 

+/**

+  Release Records to FIFO.

+  

+  @param RecordData  Point to the record buffer allocated

+                     from AcquireRecordBuffer.

+

+**/

+STATIC

+VOID

+ReleaseRecord (

+  DATA_HUB_STATUS_CODE_DATA_RECORD  *RecordData

+  )

+{

+  DATAHUB_STATUSCODE_RECORD         *Record;

+  EFI_TPL                           CurrentTpl;

+

+  Record = CR (RecordData, DATAHUB_STATUSCODE_RECORD, Data[0], DATAHUB_STATUS_CODE_SIGNATURE);

+  ASSERT (NULL != Record);

+

+  CurrentTpl = gBS->RaiseTPL (TPL_HIGH_LEVEL);

+

+  InsertTailList (&mRecordsBuffer, &Record->Node);

+  Record->Signature = 0;

+

+  gBS->RestoreTPL (CurrentTpl);

+}

+

+

 

 /**

   Report status code into DataHub.

@@ -166,6 +198,15 @@
   CHAR8                             *Format;

   UINTN                             CharCount;

 

+

+  //

+  // Use atom operation to avoid the reentant of report.

+  // If current status is not zero, then the function is reentrancy.

+  //

+  if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 0)) {

+    return EFI_DEVICE_ERROR;

+  }

+

   //

   // See whether in runtime phase or not.

   //

@@ -246,6 +287,14 @@
   UINT64                            DataRecordClass;

 

   //

+  // Use atom operation to avoid the reentant of report.

+  // If current status is not zero, then the function is reentrancy.

+  //

+  if (1 == InterlockedCompareExchange32 (&mLogDataHubStatus, 0, 1)) {

+    return;

+  }

+

+  //

   // Log DataRecord in Data Hub.

   // Journal records fifo to find all record entry.

   //

@@ -288,7 +337,13 @@
                         Size

                         );

 

+    ReleaseRecord (Record);

   }

+

+  //

+  // Restore the nest status of report

+  //

+  InterlockedCompareExchange32 (&mLogDataHubStatus, 1, 0);

 }