Ack.

Regards, Vu.

>-----Original Message-----
>From: Lennart Lund [mailto:[email protected]]
>Sent: Thursday, December 03, 2015 6:55 PM
>To: [email protected]; [email protected]
>Cc: [email protected]
>Subject: [PATCH 1 of 1] lgs: Correcting OI initializing thread handling
[#1527]
>
> osaf/services/saf/logsv/lgs/lgs.h        |    8 +-
> osaf/services/saf/logsv/lgs/lgs_amf.c    |   29 +--
> osaf/services/saf/logsv/lgs/lgs_config.c |   61 +-----
> osaf/services/saf/logsv/lgs/lgs_evt.c    |    5 +-
> osaf/services/saf/logsv/lgs/lgs_imm.c    |  323
+++++++++++++++++-------------
> osaf/services/saf/logsv/lgs/lgs_main.c   |   88 +-------
> 6 files changed, 210 insertions(+), 304 deletions(-)
>
>
>Fix in existing code to prevent possible use of imm OI handle in
>two threads at the same time. Also protecting usage of global variable
>for storing this handle and a selection object in some situations.
>Note: This must be seen as a temporary fix for this problem. Has to
>be replaced by better threaded handling of OI. See #1531 and #1609
>
>diff --git a/osaf/services/saf/logsv/lgs/lgs.h
b/osaf/services/saf/logsv/lgs/lgs.h
>--- a/osaf/services/saf/logsv/lgs/lgs.h
>+++ b/osaf/services/saf/logsv/lgs/lgs.h
>@@ -93,6 +93,7 @@ extern uint32_t mbox_msgs[NCS_IPC_PRIORI
> extern bool mbox_full[NCS_IPC_PRIORITY_MAX];
> extern uint32_t mbox_low[NCS_IPC_PRIORITY_MAX];
> extern pthread_mutex_t lgs_mbox_init_mutex;
>+extern pthread_mutex_t lgs_OI_init_mutex;
>
> extern uint32_t lgs_configure_mailbox(void);
>
>@@ -105,12 +106,15 @@ extern uint32_t lgs_mds_msg_send(lgs_cb_
>                             MDS_DEST *dest, MDS_SYNC_SND_CTXT *mds_ctxt,
>MDS_SEND_PRIORITY_TYPE prio);
>
> extern SaAisErrorT lgs_imm_create_configStream(lgs_cb_t *cb);
>-extern void lgs_imm_impl_restore(lgs_cb_t *cb);
>-extern SaAisErrorT lgs_imm_init_OI(lgs_cb_t *cb);
> extern void logRootDirectory_filemove(
>               const char *new_logRootDirectory,
>               const char *old_logRootDirectory,
>               time_t *cur_time_in);
> extern void logDataGroupname_fileown(const char
>*new_logDataGroupname);
>
>+extern void lgs_imm_impl_reinit_nonblocking(lgs_cb_t *cb);
>+extern void lgs_imm_init_OI_handle(SaImmOiHandleT *immOiHandle,
>+      SaSelectionObjectT *immSelectionObject);
>+extern void lgs_imm_impl_set(SaImmOiHandleT immOiHandle);
>+
> #endif   /* ifndef __LGS_H */
>diff --git a/osaf/services/saf/logsv/lgs/lgs_amf.c
>b/osaf/services/saf/logsv/lgs/lgs_amf.c
>--- a/osaf/services/saf/logsv/lgs/lgs_amf.c
>+++ b/osaf/services/saf/logsv/lgs/lgs_amf.c
>@@ -64,33 +64,8 @@ static SaAisErrorT amf_active_state_hand
>               goto done;
>       }
>
>-      /* switch over, become implementer
>-       */
>-      immutilWrapperProfile.nTries = 250; /* LOG will be blocked until IMM
>responds */
>-      immutilWrapperProfile.errorsAreFatal = 0;
>-      if ((error = immutil_saImmOiImplementerSet(lgs_cb->immOiHandle,
>"safLogService"))
>-                      != SA_AIS_OK) {
>-              LOG_ER("saImmOiClassImplementerSet (safLogService) failed:
>%d", error);
>-              goto done;
>-      }
>-      if ((error = immutil_saImmOiClassImplementerSet(lgs_cb-
>>immOiHandle,
>-                      "SaLogStreamConfig")) != SA_AIS_OK) {
>-              LOG_ER("saImmOiClassImplementerSet (SaLogStreamConfig)
>failed: %d", error);
>-              goto done;
>-      }
>-      /* Do this only if the log service configuration class exists */
>-      if (*(bool*)
>lgs_cfg_get(LGS_IMM_LOG_OPENSAFLOGCONFIG_CLASS_EXIST)) {
>-              if ((error = immutil_saImmOiClassImplementerSet(cb-
>>immOiHandle, "OpenSafLogConfig"))
>-                              != SA_AIS_OK) {
>-                      LOG_ER("saImmOiClassImplementerSet
>(OpenSafLogConfig) failed: %d", error);
>-                      goto done;
>-              }
>-
>-              /* Create a log service configuration runtime object if the
>-               * configuration runtime class exist and no object exist
>-               */
>-              conf_runtime_obj_create(cb->immOiHandle);
>-      }
>+      lgs_imm_impl_set(cb->immOiHandle);
>+      conf_runtime_obj_create(cb->immOiHandle);
>
>       /* check existing streams */
>       stream = log_stream_getnext_by_name(NULL);
>diff --git a/osaf/services/saf/logsv/lgs/lgs_config.c
>b/osaf/services/saf/logsv/lgs/lgs_config.c
>--- a/osaf/services/saf/logsv/lgs/lgs_config.c
>+++ b/osaf/services/saf/logsv/lgs/lgs_config.c
>@@ -1124,56 +1124,6 @@ static void read_log_config_environ_var_
>       TRACE_LEAVE();
> }
>
>-/**
>- * Become class implementer for the SaLogStreamConfig class
>- * If HA state is ACTIVE
>- *
>- * @param immOiHandle[in]
>- * @return -1 on error
>- */
>-static int config_class_impl_set(SaImmOiHandleT immOiHandle,
>SaAmfHAStateT ha_state)
>-{
>-      int rc = 0;
>-      SaAisErrorT ais_rc = SA_AIS_OK;
>-      struct ImmutilWrapperProfile immutilWrapperProfile_tmp;
>-
>-      TRACE_ENTER2("immOiHandle = %lld, ha_state = %d (1 = Active)",
>-              immOiHandle, ha_state);
>-
>-      if (ha_state != SA_AMF_HA_ACTIVE) {
>-              /* We are standby and cannot become implementer */
>-              TRACE("HA state STANDBY");
>-              TRACE_LEAVE();
>-              return 0;
>-      }
>-
>-      /* Save immutil settings */
>-      immutilWrapperProfile_tmp.errorsAreFatal =
>immutilWrapperProfile.errorsAreFatal;
>-      immutilWrapperProfile_tmp.nTries = immutilWrapperProfile.nTries;
>-
>-      /* Allow missed sync of large data to complete */
>-      immutilWrapperProfile.nTries = 250;
>-      /* Do not assert on error */
>-      immutilWrapperProfile.errorsAreFatal = 0;
>-
>-      ais_rc = immutil_saImmOiClassImplementerSet(immOiHandle,
>"OpenSafLogConfig");
>-      if (ais_rc != SA_AIS_OK) {
>-              /* immutil_saImmOiClassImplementerSet Fail
>-               * Class may not exist
>-               */
>-              LOG_WA("%s: saImmOiClassImplementerSet Fail
>%s",__FUNCTION__,
>-                      saf_error(ais_rc));
>-              rc = -1;
>-      }
>-
>-      /* Restore immutil settings */
>-      immutilWrapperProfile.errorsAreFatal =
>immutilWrapperProfile_tmp.errorsAreFatal;
>-      immutilWrapperProfile.nTries = immutilWrapperProfile_tmp.nTries;
>-
>-      TRACE_LEAVE();
>-      return rc;
>-}
>-
>
>/*****************************************************************
>*************
>  * Public functions for handling configuration information
>
>******************************************************************
>************/
>@@ -1184,23 +1134,16 @@ static int config_class_impl_set(SaImmOi
>  */
> void lgs_cfg_init(SaImmOiHandleT immOiHandle, SaAmfHAStateT ha_state)
> {
>-      int int_rc = 0;
>-
>       TRACE_ENTER2("immOiHandle = %lld", immOiHandle);
>+
>       /* Initiate the default values for all parameters
>        */
>       init_default();
>
>       /* Read configuration step 1
>-       * Become class implementer for SaLogStreamConfig class
>        * Read all values from the log service configuration object
>        */
>-      int_rc = config_class_impl_set(immOiHandle, ha_state);
>-      if (int_rc != -1) {
>-              read_logsv_config_obj_2();
>-      } else {
>-              TRACE("Failed to become class implementer. Config object not
>read");
>-      }
>+      read_logsv_config_obj_2();
>
>       /* Read configuration step 2
>        * Get configuration data from environment variables.
>diff --git a/osaf/services/saf/logsv/lgs/lgs_evt.c
>b/osaf/services/saf/logsv/lgs/lgs_evt.c
>--- a/osaf/services/saf/logsv/lgs/lgs_evt.c
>+++ b/osaf/services/saf/logsv/lgs/lgs_evt.c
>@@ -522,9 +522,8 @@ static uint32_t proc_rda_cb_msg(lgsv_lgs
>                       exit(EXIT_FAILURE);
>               }
>
>-              /* fail over, become implementer
>-               * Declare implementership from a separate thread */
>-              lgs_imm_impl_restore(lgs_cb);
>+              /* fail over, become implementer */
>+              lgs_imm_impl_set(lgs_cb->immOiHandle);
>
>               /* Agent down list has to be processed first */
>               lgs_process_lga_down_list();
>diff --git a/osaf/services/saf/logsv/lgs/lgs_imm.c
>b/osaf/services/saf/logsv/lgs/lgs_imm.c
>--- a/osaf/services/saf/logsv/lgs/lgs_imm.c
>+++ b/osaf/services/saf/logsv/lgs/lgs_imm.c
>@@ -58,6 +58,11 @@
>  * ----------------
>  */
>
>+/* Used for protecting global imm OI handle and selection object during
>+ * initialize of OI
>+ */
>+pthread_mutex_t lgs_OI_init_mutex = PTHREAD_MUTEX_INITIALIZER;
>+
> /* Used for checkpointing time when files are closed */
> static time_t chkp_file_close_time = 0;
>
>@@ -2739,114 +2744,14 @@ SaAisErrorT lgs_imm_create_configStream(
> }
>
> /**
>- * Thread
>- * Restore object and class implementer/applier. Wait max
>- * 'max_waiting_time_ms'.
>- * @param _cb
>- *
>- * @return void*
>- */
>-static void *imm_impl_restore_thread(void *_cb)
>-{
>-      SaAisErrorT rc = SA_AIS_OK;
>-      int msecs_waited;
>-      lgs_cb_t *cb = (lgs_cb_t *)_cb;
>-
>-      TRACE_ENTER();
>-
>-      /* Become object implementer
>-       */
>-      msecs_waited = 0;
>-      rc = saImmOiImplementerSet(cb->immOiHandle, implementerName);
>-      while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc == SA_AIS_ERR_EXIST))
>&&
>-                      (msecs_waited < max_waiting_time_60s)) {
>-              usleep(sleep_delay_ms * 1000);
>-              msecs_waited += sleep_delay_ms;
>-              rc = saImmOiImplementerSet(cb->immOiHandle,
>implementerName);
>-      }
>-      if (rc != SA_AIS_OK) {
>-              LOG_ER("saImmOiImplementerSet failed %u", rc);
>-              exit(EXIT_FAILURE);
>-      }
>-
>-      /* Become class implementer for the SaLogStreamConfig
>-       * Become class implementer for the OpenSafLogConfig class if it
exists
>-       */
>-      if ( true == *(bool*)
>lgs_cfg_get(LGS_IMM_LOG_OPENSAFLOGCONFIG_CLASS_EXIST)) {
>-              (void)immutil_saImmOiClassImplementerSet(cb-
>>immOiHandle, "OpenSafLogConfig");
>-              msecs_waited = 0;
>-              rc = saImmOiClassImplementerSet(cb->immOiHandle,
>"OpenSafLogConfig");
>-              while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc ==
>SA_AIS_ERR_EXIST))
>-                              && (msecs_waited < max_waiting_time_60s)) {
>-                      usleep(sleep_delay_ms * 1000);
>-                      msecs_waited += sleep_delay_ms;
>-                      rc = saImmOiClassImplementerSet(cb->immOiHandle,
>"OpenSafLogConfig");
>-              }
>-              if (rc != SA_AIS_OK) {
>-                      LOG_ER("saImmOiClassImplementerSet
>OpenSafLogConfig failed %u", rc);
>-                      exit(EXIT_FAILURE);
>-              }
>-      }
>-
>-      msecs_waited = 0;
>-      rc = saImmOiClassImplementerSet(cb->immOiHandle,
>"SaLogStreamConfig");
>-      while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc == SA_AIS_ERR_EXIST))
>-                      && (msecs_waited < max_waiting_time_60s)) {
>-              usleep(sleep_delay_ms * 1000);
>-              msecs_waited += sleep_delay_ms;
>-              rc = saImmOiClassImplementerSet(cb->immOiHandle,
>"SaLogStreamConfig");
>-      }
>-      if (rc != SA_AIS_OK) {
>-              LOG_ER("saImmOiClassImplementerSet SaLogStreamConfig
>failed %u", rc);
>-              exit(EXIT_FAILURE);
>-      }
>-
>-      TRACE_LEAVE();
>-      return NULL;
>-}
>-
>-/**
>- * Restore object and class implementer, non-blocking.
>- * Remove: Become object and class implementer or applier, non-blocking.
>- * @param cb
>- */
>-void lgs_imm_impl_restore(lgs_cb_t *cb)
>-{
>-      pthread_t thread;
>-      pthread_attr_t attr;
>-
>-      TRACE_ENTER();
>-
>-      /* In active state: Become object implementer.
>-       */
>-      if (cb->ha_state == SA_AMF_HA_STANDBY) {
>-              return;
>-      }
>-
>-
>-      pthread_attr_init(&attr);
>-      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
>-
>-      if (pthread_create(&thread, &attr, imm_impl_restore_thread, cb) !=
0)
>{
>-              LOG_ER("pthread_create FAILED: %s", strerror(errno));
>-              exit(EXIT_FAILURE);
>-      }
>-
>-      pthread_attr_destroy(&attr);
>-
>-      TRACE_LEAVE();
>-}
>-
>-/**
>  * Initialize the OI interface and get a selection object.
>  * Become OI for safLogService if Active
>  *
>- * Wait max 'max_waiting_time_ms'.
>- * @param cb
>- *
>- * @return SaAisErrorT
>+ * @param immOiHandle[out]
>+ * @param immSelectionObject[out]
>  */
>-SaAisErrorT lgs_imm_init_OI(lgs_cb_t *cb)
>+void lgs_imm_init_OI_handle(SaImmOiHandleT *immOiHandle,
>+      SaSelectionObjectT *immSelectionObject)
> {
>       SaAisErrorT rc;
>       int msecs_waited;
>@@ -2855,56 +2760,198 @@ SaAisErrorT lgs_imm_init_OI(lgs_cb_t *cb
>
>       /* Initialize IMM OI service */
>       msecs_waited = 0;
>-      rc = saImmOiInitialize_2(&cb->immOiHandle, &callbacks,
>&immVersion);
>+      rc = saImmOiInitialize_2(immOiHandle, &callbacks, &immVersion);
>       while ((rc == SA_AIS_ERR_TRY_AGAIN) && (msecs_waited <
>max_waiting_time_60s)) {
>               usleep(sleep_delay_ms * 1000);
>               msecs_waited += sleep_delay_ms;
>-              rc = saImmOiInitialize_2(&cb->immOiHandle, &callbacks,
>&immVersion);
>+              rc = saImmOiInitialize_2(immOiHandle, &callbacks,
>&immVersion);
>       }
>       if (rc != SA_AIS_OK) {
>-              LOG_ER("saImmOiInitialize_2 Failed %u", rc);
>-              return rc;
>-      }
>-      TRACE("%s: saImmOiInitialize_2() Done",__FUNCTION__);
>-
>-      /* If started as Active */
>-      if (cb->ha_state == SA_AMF_HA_ACTIVE) {
>-              /* Become Object Implementer for the log service */
>-              msecs_waited = 0;
>-              rc = saImmOiImplementerSet(cb->immOiHandle,
>implementerName);
>-              while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc ==
>SA_AIS_ERR_EXIST)) &&
>-                              (msecs_waited < max_waiting_time_60s)) {
>-                      usleep(sleep_delay_ms * 1000);
>-                      msecs_waited += sleep_delay_ms;
>-                      rc = saImmOiImplementerSet(cb->immOiHandle,
>implementerName);
>-              }
>-              if (rc != SA_AIS_OK) {
>-                      LOG_ER("saImmOiImplementerSet Failed %u", rc);
>-                      exit(EXIT_FAILURE);
>-              }
>-              TRACE("%s: saImmOiImplementerSet() for %s Done",
>-                      __FUNCTION__, implementerName);
>-
>-              /* Create the runtime object for showing the actual
>-               * log server configuration
>-               */
>-              conf_runtime_obj_create(cb->immOiHandle);
>+              lgs_exit("saImmOiInitialize_2 failed",
>SA_AMF_COMPONENT_RESTART);
>       }
>
>       /* Get selection object for event handling */
>       msecs_waited = 0;
>-      rc = saImmOiSelectionObjectGet(cb->immOiHandle, &cb-
>>immSelectionObject);
>+      rc = saImmOiSelectionObjectGet(*immOiHandle, immSelectionObject);
>       while ((rc == SA_AIS_ERR_TRY_AGAIN) && (msecs_waited <
>max_waiting_time_10s)) {
>               usleep(sleep_delay_ms * 1000);
>               msecs_waited += sleep_delay_ms;
>-              rc = saImmOiSelectionObjectGet(cb->immOiHandle, &cb-
>>immSelectionObject);
>+              rc = saImmOiSelectionObjectGet(*immOiHandle,
>immSelectionObject);
>       }
>       if (rc != SA_AIS_OK) {
>-              LOG_ER("saImmOiSelectionObjectGet failed %u", rc);
>+              lgs_exit("saImmOiSelectionObjectGet failed",
>SA_AMF_COMPONENT_RESTART);
>+      }
>+
>+      TRACE_LEAVE();
>+}
>+
>+/**
>+ * Does the sequence of setting an implementer name and class implementer
>+ *
>+ * @param immOiHandle[in]
>+ * @return SaAisErrorT
>+ */
>+static SaAisErrorT imm_impl_set_sequence(SaImmOiHandleT immOiHandle)
>+{
>+      SaAisErrorT rc = SA_AIS_OK;
>+      int msecs_waited;
>+
>+      TRACE_ENTER();
>+
>+      /* Become object implementer
>+       */
>+      msecs_waited = 0;
>+      rc = saImmOiImplementerSet(immOiHandle, implementerName);
>+      while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc == SA_AIS_ERR_EXIST))
>&&
>+                      (msecs_waited < max_waiting_time_60s)) {
>+              usleep(sleep_delay_ms * 1000);
>+              msecs_waited += sleep_delay_ms;
>+              rc = saImmOiImplementerSet(immOiHandle,
>implementerName);
>+      }
>+      if (rc != SA_AIS_OK) {
>+              TRACE("saImmOiImplementerSet failed %s", saf_error(rc));
>+              goto done;
>+      }
>+
>+      /* Become class implementer for the SaLogStreamConfig
>+       * Become class implementer for the OpenSafLogConfig class if it
exists
>+       */
>+      if ( true == *(bool*)
>lgs_cfg_get(LGS_IMM_LOG_OPENSAFLOGCONFIG_CLASS_EXIST)) {
>+              (void)immutil_saImmOiClassImplementerSet(immOiHandle,
>"OpenSafLogConfig");
>+              msecs_waited = 0;
>+              rc = saImmOiClassImplementerSet(immOiHandle,
>"OpenSafLogConfig");
>+              while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc ==
>SA_AIS_ERR_EXIST))
>+                              && (msecs_waited < max_waiting_time_60s)) {
>+                      usleep(sleep_delay_ms * 1000);
>+                      msecs_waited += sleep_delay_ms;
>+                      rc = saImmOiClassImplementerSet(immOiHandle,
>"OpenSafLogConfig");
>+              }
>+              if (rc != SA_AIS_OK) {
>+                      TRACE("saImmOiClassImplementerSet
>OpenSafLogConfig failed %s", saf_error(rc));
>+                      goto done;
>+              }
>+      }
>+
>+      if (*(bool*)
>lgs_cfg_get(LGS_IMM_LOG_OPENSAFLOGCONFIG_CLASS_EXIST)) {
>+              msecs_waited = 0;
>+              rc = saImmOiClassImplementerSet(immOiHandle,
>"SaLogStreamConfig");
>+              while (((rc == SA_AIS_ERR_TRY_AGAIN) || (rc ==
>SA_AIS_ERR_EXIST))
>+                              && (msecs_waited < max_waiting_time_60s)) {
>+                      usleep(sleep_delay_ms * 1000);
>+                      msecs_waited += sleep_delay_ms;
>+                      rc = saImmOiClassImplementerSet(immOiHandle,
>"SaLogStreamConfig");
>+              }
>+              if (rc != SA_AIS_OK) {
>+                      TRACE("saImmOiClassImplementerSet
>SaLogStreamConfig failed %u", rc);
>+                      goto done;
>+              }
>+      }
>+
>+done:
>+      return rc;
>+      TRACE_LEAVE();
>+}
>+
>+/**
>+ * Set implementer name and become class implementer.
>+ * This function will block until done.
>+ *
>+ * @param cb
>+ */
>+void lgs_imm_impl_set(SaImmOiHandleT immOiHandle)
>+{
>+      SaAisErrorT rc = SA_AIS_OK;
>+
>+      TRACE_ENTER();
>+
>+      rc = imm_impl_set_sequence(immOiHandle);
>+      if (rc != SA_AIS_OK) {
>+              lgs_exit("Becoming OI implementer failed",
>SA_AMF_COMPONENT_RESTART);
>+      }
>+
>+      TRACE_LEAVE();
>+}
>+
>+/**
>+ * Thread
>+ * Restore object and class implementer/applier.
>+ *
>+ * @param _cb[in]
>+ */
>+static void *imm_impl_init_thread(void *_cb)
>+{
>+      lgs_cb_t *cb = (lgs_cb_t *)_cb;
>+      SaSelectionObjectT immSelectionObject = 0;
>+      SaImmOiHandleT immOiHandle = 0;
>+      SaAisErrorT rc = SA_AIS_OK;
>+
>+      TRACE_ENTER();
>+
>+      /* Initialize handles and become implementer */
>+      lgs_imm_init_OI_handle(&immOiHandle, &immSelectionObject);
>+      rc = imm_impl_set_sequence(immOiHandle);
>+      if (rc != SA_AIS_OK) {
>+              lgs_exit("Becoming OI implementer failed",
>SA_AMF_COMPONENT_RESTART);
>+      }
>+
>+      /* Store handle and selection object.
>+       * Protect if the poll loop in main is released during the storage
>+       * sequence.
>+       */
>+      osaf_mutex_lock_ordie(&lgs_OI_init_mutex);
>+      cb->immSelectionObject = immSelectionObject;
>+      cb->immOiHandle = immOiHandle;
>+      osaf_mutex_unlock_ordie(&lgs_OI_init_mutex);
>+
>+      /* Activate the poll loop in main()
>+       * This will reinstall IMM poll event handling
>+       */
>+      lgsv_lgs_evt_t *lgsv_evt;
>+      lgsv_evt = calloc(1, sizeof(lgsv_lgs_evt_t));
>+      osafassert(lgsv_evt);
>+      lgsv_evt->evt_type = LGSV_EVT_NO_OP;
>+      if (m_NCS_IPC_SEND(&lgs_mbx, lgsv_evt, LGS_IPC_PRIO_CTRL_MSGS) !=
>+              NCSCC_RC_SUCCESS) {
>+              LOG_WA("imm_reinit_thread failed to send IPC message to
>main thread");
>+              /*
>+               * Se no reason why this would happen. But if it does at
least
>there
>+               * is something in the syslog. The main thread should still
pick
>up
>+               * the new imm FD when there is a healthcheck, but it could
>take
>+               *minutes.
>+               */
>+              free(lgsv_evt);
>+      }
>+
>+      TRACE_LEAVE();
>+      return NULL;
>+}
>+
>+/**
>+ * In a separate thread:
>+ * Initiate IMM OI handle and selection object
>+ * Create imm implementer for log IMM objects
>+ * When complete:
>+ * Store the new handle and selection object in the cb store.
>+ * Activate the poll loop in main() by sending an empty mailbox message
>+ *
>+ * @param cb[out]
>+ */
>+void lgs_imm_impl_reinit_nonblocking(lgs_cb_t *cb)
>+{
>+      pthread_t thread;
>+      pthread_attr_t attr;
>+
>+      TRACE_ENTER();
>+
>+      pthread_attr_init(&attr);
>+      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
>+
>+      if (pthread_create(&thread, &attr, imm_impl_init_thread, cb) != 0) {
>+              LOG_ER("pthread_create FAILED: %s", strerror(errno));
>               exit(EXIT_FAILURE);
>       }
>
>+      pthread_attr_destroy(&attr);
>+
>       TRACE_LEAVE();
>-
>-      return rc;
> }
>diff --git a/osaf/services/saf/logsv/lgs/lgs_main.c
>b/osaf/services/saf/logsv/lgs/lgs_main.c
>--- a/osaf/services/saf/logsv/lgs/lgs_main.c
>+++ b/osaf/services/saf/logsv/lgs/lgs_main.c
>@@ -227,14 +227,9 @@ static uint32_t log_initialize(void)
>               goto done;
>       }
>
>-      /* Initialize IMM OI and get corresponding OI selection object
>-       * Become OI for safLogService if Active
>-       * IMM OI handle and IMM selection object is saved in lgs_cb
>-       */
>-      if ((rc = lgs_imm_init_OI(lgs_cb)) != SA_AIS_OK) {
>-              LOG_ER("lgs_imm_init FAILED");
>-              goto done;
>-      }
>+      /* Initialize IMM OI handle and selection object */
>+      lgs_imm_init_OI_handle(&lgs_cb->immOiHandle, &lgs_cb-
>>immSelectionObject);
>+
>       TRACE("IMM init done: lgs_cb->immOiHandle = %lld", lgs_cb-
>>immOiHandle);
>
>       /* Initialize log configuration
>@@ -325,6 +320,10 @@ static uint32_t log_initialize(void)
>       }
>
>       if (lgs_cb->ha_state == SA_AMF_HA_ACTIVE) {
>+              /* Become OI. We will be blocked here until done */
>+              lgs_imm_impl_set(lgs_cb->immOiHandle);
>+              conf_runtime_obj_create(lgs_cb->immOiHandle);
>+
>               /* Create streams that has configuration objects and become
>                * class implementer for the SaLogStreamConfig class
>                */
>@@ -353,72 +352,6 @@ done:
> }
>
> /**
>- * Wait a while on IMM and initialize, sel obj get & implementer
>- * set.
>- *
>- * @param _cb
>- *
>- * @return void*
>- */
>-static void *imm_reinit_thread(void *_cb)
>-{
>-      SaAisErrorT error;
>-      lgs_cb_t *cb = (lgs_cb_t *)_cb;
>-      lgsv_lgs_evt_t *lgsv_evt;
>-
>-      TRACE_ENTER();
>-
>-      if ((error = lgs_imm_init_OI(cb)) != SA_AIS_OK) {
>-              LOG_ER("lgs_imm_init FAILED: %u", error);
>-              exit(EXIT_FAILURE);
>-      }
>-
>-      lgs_imm_impl_restore(cb);
>-
>-      /* Wake up the main thread so it discovers the new imm descriptor.
*/
>-      lgsv_evt = calloc(1, sizeof(lgsv_lgs_evt_t));
>-      osafassert(lgsv_evt);
>-      lgsv_evt->evt_type = LGSV_EVT_NO_OP;
>-      if (m_NCS_IPC_SEND(&lgs_mbx, lgsv_evt, LGS_IPC_PRIO_CTRL_MSGS) !=
>-              NCSCC_RC_SUCCESS) {
>-              LOG_WA("imm_reinit_thread failed to send IPC message to
>main thread");
>-              /*
>-               * Se no reason why thos would happen. But if it does at
least
>there
>-               * is something in the syslog. The main thread should still
pick
>up
>-               * the new imm FD when there is a healthcheck, but it could
>take
>-               *minutes.
>-               */
>-              free(lgsv_evt);
>-      }
>-
>-      TRACE_LEAVE();
>-      return NULL;
>-}
>-
>-/**
>- * Start a background thread to do IMM reinitialization.
>- *
>- * @param cb
>- */
>-static void imm_reinit_bg(lgs_cb_t *cb)
>-{
>-      pthread_t thread;
>-      pthread_attr_t attr;
>-      pthread_attr_init(&attr);
>-      pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
>-
>-      TRACE_ENTER();
>-      if (pthread_create(&thread, &attr, imm_reinit_thread, cb) != 0) {
>-              LOG_ER("pthread_create FAILED: %s", strerror(errno));
>-              exit(EXIT_FAILURE);
>-      }
>-
>-      pthread_attr_destroy(&attr);
>-
>-      TRACE_LEAVE();
>-}
>-
>-/**
>  * The main routine for the lgs daemon.
>  * @param argc
>  * @param argv
>@@ -457,6 +390,10 @@ int main(int argc, char *argv[])
>
>       while (1) {
>
>+              /* Protect since the reinit thread may be in the process of
>+               * changing the values
>+               */
>+              osaf_mutex_lock_ordie(&lgs_OI_init_mutex);
>               if (lgs_cb->immOiHandle != 0) {
>                       fds[FD_IMM].fd = lgs_cb->immSelectionObject;
>                       fds[FD_IMM].events = POLLIN;
>@@ -464,6 +401,7 @@ int main(int argc, char *argv[])
>               } else {
>                       nfds = FD_IMM;
>               }
>+              osaf_mutex_unlock_ordie(&lgs_OI_init_mutex);
>
>               int ret = poll(fds, nfds, -1);
>
>@@ -538,7 +476,7 @@ int main(int argc, char *argv[])
>                               lgs_cb->immOiHandle = 0;
>
>                               /* Initiate IMM reinitializtion in the
>background */
>-                              imm_reinit_bg(lgs_cb);
>+                              lgs_imm_impl_reinit_nonblocking(lgs_cb);
>                       } else if (error != SA_AIS_OK) {
>                               LOG_ER("saImmOiDispatch FAILED: %u", error);
>                               break;


------------------------------------------------------------------------------
Go from Idea to Many App Stores Faster with Intel(R) XDK
Give your users amazing mobile app experiences with Intel(R) XDK.
Use one codebase in this all-in-one HTML5 development environment.
Design, debug & build mobile apps & 2D/3D high-impact games for multiple OSs.
http://pubads.g.doubleclick.net/gampad/clk?id=254741911&iu=/4140
_______________________________________________
Opensaf-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to