osaf/libs/common/immsv/immsv_evt.c               |  56 ++++++++++++++-
 osaf/libs/common/immsv/include/immsv_evt.h       |   4 +
 osaf/libs/common/immsv/include/immsv_evt_model.h |   1 +
 osaf/services/saf/immsv/immd/immd_evt.c          |   9 ++-
 osaf/services/saf/immsv/immnd/ImmModel.cc        |  89 ++++++++++++++++++-----
 osaf/services/saf/immsv/immnd/ImmModel.hh        |   6 +-
 osaf/services/saf/immsv/immnd/immnd_evt.c        |  38 ++++++++-
 osaf/services/saf/immsv/immnd/immnd_init.h       |   8 +-
 8 files changed, 175 insertions(+), 36 deletions(-)


When an implementer is set, the configurable timeout is sent to IMM service. 
The configurable timeout is used for calculating timeouts for OI callbacks and 
waiting on search replies from RTA update callback.

diff --git a/osaf/libs/common/immsv/immsv_evt.c 
b/osaf/libs/common/immsv/immsv_evt.c
--- a/osaf/libs/common/immsv/immsv_evt.c
+++ b/osaf/libs/common/immsv/immsv_evt.c
@@ -64,6 +64,7 @@ static const char *immd_evt_names[] = {
        "IMMD_EVT_ND2D_FEVS_REQ_2",
        "IMMD_EVT_ND2D_LOADING_COMPLETED",
        "IMMD_EVT_ND2D_2PBE_PRELOAD",
+       "IMMD_EVT_ND2D_IMPLSET_REQ_2",
        "undefined (high)"
 };
 
@@ -173,6 +174,8 @@ static const char *immnd_evt_names[] = {
        "IMMND_EVT_A2ND_CL_TIMEOUT",
        "IMMND_EVT_A2ND_ACCESSOR_GET",
        "IMMND_EVT_A2ND_CCB_VALIDATE",  /* saImmOmCcbValidate */
+       "IMMND_EVT_A2ND_OI_IMPL_SET_2", /* saImmOiImplementerSet */
+       "IMMND_EVT_D2ND_IMPLSET_RSP_2", /* Implementer set reply from D with 
impl id */
        "undefined (high)"
 };
 
@@ -1511,7 +1514,8 @@ static uint32_t immsv_evt_enc_sublevels(
                        (i_evt->info.immd.type == IMMD_EVT_ND2D_FEVS_REQ_2)) {
                        IMMSV_OCTET_STRING *os = 
&(i_evt->info.immd.info.fevsReq.msg);
                        immsv_evt_enc_inline_string(o_ub, os);
-               } else if (i_evt->info.immd.type == IMMD_EVT_ND2D_IMPLSET_REQ) {
+               } else if ((i_evt->info.immd.type == IMMD_EVT_ND2D_IMPLSET_REQ) 
||
+                               (i_evt->info.immd.type == 
IMMD_EVT_ND2D_IMPLSET_REQ_2)) {
                        IMMSV_OCTET_STRING *os = 
&(i_evt->info.immd.info.impl_set.r.impl_name);
                        if(!immsv_evt_enc_inline_text(__LINE__, o_ub, os)) {
                                return NCSCC_RC_OUT_OF_MEM;
@@ -1564,7 +1568,9 @@ static uint32_t immsv_evt_enc_sublevels(
                        IMMSV_OCTET_STRING *os = 
&(i_evt->info.immnd.info.fevsReq.msg);
                        immsv_evt_enc_inline_string(o_ub, os);
                } else if ((i_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_IMPL_SET) ||
+                          (i_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_IMPL_SET_2) ||
                           (i_evt->info.immnd.type == 
IMMND_EVT_D2ND_IMPLSET_RSP) ||
+                          (i_evt->info.immnd.type == 
IMMND_EVT_D2ND_IMPLSET_RSP_2) ||
                           (i_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_CL_IMPL_SET) ||
                           (i_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_CL_IMPL_REL) ||
                           (i_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_OBJ_IMPL_SET) ||
@@ -2141,7 +2147,8 @@ static uint32_t immsv_evt_dec_sublevels(
                    (o_evt->info.immd.type == IMMD_EVT_ND2D_FEVS_REQ_2)) {
                        IMMSV_OCTET_STRING *os = 
&(o_evt->info.immd.info.fevsReq.msg);
                        immsv_evt_dec_inline_string(i_ub, os);
-               } else if (o_evt->info.immd.type == IMMD_EVT_ND2D_IMPLSET_REQ) {
+               } else if ((o_evt->info.immd.type == IMMD_EVT_ND2D_IMPLSET_REQ) 
||
+                               (o_evt->info.immd.type == 
IMMD_EVT_ND2D_IMPLSET_REQ_2)) {
                        IMMSV_OCTET_STRING *os = 
&(o_evt->info.immd.info.impl_set.r.impl_name);
                        immsv_evt_dec_inline_string(i_ub, os);
                } else if (o_evt->info.immd.type == 
IMMD_EVT_ND2D_OI_OBJ_MODIFY) {
@@ -2177,7 +2184,9 @@ static uint32_t immsv_evt_dec_sublevels(
                        immsv_evt_dec_inline_string(i_ub, os);
                } else
                    if ((o_evt->info.immnd.type == IMMND_EVT_A2ND_OI_IMPL_SET) 
||
+                       (o_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_IMPL_SET_2) ||
                        (o_evt->info.immnd.type == IMMND_EVT_D2ND_IMPLSET_RSP) 
||
+                       (o_evt->info.immnd.type == 
IMMND_EVT_D2ND_IMPLSET_RSP_2) ||
                        (o_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_CL_IMPL_SET) ||
                        (o_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_CL_IMPL_REL) ||
                        (o_evt->info.immnd.type == 
IMMND_EVT_A2ND_OI_OBJ_IMPL_SET) ||
@@ -2949,6 +2958,7 @@ static uint32_t immsv_evt_enc_toplevel(I
                        break;
 
                case IMMD_EVT_ND2D_IMPLSET_REQ: /*OiImplementerSet */
+               case IMMD_EVT_ND2D_IMPLSET_REQ_2:       /*OiImplementerSet */
                        IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 8);
                        ncs_encode_64bit(&p8, 
immdevt->info.impl_set.reply_dest);
                        ncs_enc_claim_space(o_ub, 8);
@@ -2966,6 +2976,12 @@ static uint32_t immsv_evt_enc_toplevel(I
                        ncs_encode_32bit(&p8, immdevt->info.impl_set.r.scope);
                        ncs_enc_claim_space(o_ub, 4);
 
+                       if(immdevt->type == IMMD_EVT_ND2D_IMPLSET_REQ_2) {
+                               IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 4);
+                               ncs_encode_32bit(&p8, 
immdevt->info.impl_set.r.oi_timeout);
+                               ncs_enc_claim_space(o_ub, 4);
+                       }
+
                        /*intentional fall through - encode impl_id */
                case IMMD_EVT_ND2D_DISCARD_IMPL:        /*Internal discard 
implementer message */
 
@@ -3274,6 +3290,7 @@ static uint32_t immsv_evt_enc_toplevel(I
                        break;
 
                case IMMND_EVT_A2ND_OI_IMPL_SET:        /* 
saImmOiImplementerSet */
+               case IMMND_EVT_A2ND_OI_IMPL_SET_2:      /* 
saImmOiImplementerSet */
                        IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 8);
                        ncs_encode_64bit(&p8, 
immndevt->info.implSet.client_hdl);
                        ncs_enc_claim_space(o_ub, 8);
@@ -3284,6 +3301,12 @@ static uint32_t immsv_evt_enc_toplevel(I
                        /* immndevt->info.implSet.impl_name.buf encoded by 
sublevel */
 
                        /*skip scope & impl_id */
+
+                       if(immndevt->type == IMMND_EVT_A2ND_OI_IMPL_SET_2) {
+                               IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 4);
+                               ncs_encode_32bit(&p8, 
immndevt->info.implSet.oi_timeout);
+                               ncs_enc_claim_space(o_ub, 4);
+                       }
                        break;
 
                        /*Fevs call IMMA->IMMD->IMMNDs have to suport non-flat 
encoding */
@@ -3760,6 +3783,7 @@ static uint32_t immsv_evt_enc_toplevel(I
                        break;
 
                case IMMND_EVT_D2ND_IMPLSET_RSP:        /* Impl set reply from 
D with impl id */
+               case IMMND_EVT_D2ND_IMPLSET_RSP_2:
                        IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 8);
                        ncs_encode_64bit(&p8, 
immndevt->info.implSet.client_hdl);
                        ncs_enc_claim_space(o_ub, 8);
@@ -3776,6 +3800,12 @@ static uint32_t immsv_evt_enc_toplevel(I
                        IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 4);
                        ncs_encode_32bit(&p8, immndevt->info.implSet.scope);
                        ncs_enc_claim_space(o_ub, 4);
+
+                       if(immndevt->type == IMMND_EVT_D2ND_IMPLSET_RSP_2) {
+                               IMMSV_RSRV_SPACE_ASSERT(p8, o_ub, 4);
+                               ncs_encode_32bit(&p8, 
immndevt->info.implSet.oi_timeout);
+                               ncs_enc_claim_space(o_ub, 4);
+                       }
                        break;
 
                case IMMND_EVT_D2ND_DISCARD_IMPL:       /* Discard implementer 
broadcast to NDs */
@@ -4263,6 +4293,7 @@ static uint32_t immsv_evt_dec_toplevel(N
                        break;
 
                case IMMD_EVT_ND2D_IMPLSET_REQ: /*OiImplementerSet */
+               case IMMD_EVT_ND2D_IMPLSET_REQ_2:       /*OiImplementerSet */
                        IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 8);
                        immdevt->info.impl_set.reply_dest = 
ncs_decode_64bit(&p8);
                        ncs_dec_skip_space(i_ub, 8);
@@ -4280,6 +4311,14 @@ static uint32_t immsv_evt_dec_toplevel(N
                        immdevt->info.impl_set.r.scope = ncs_decode_32bit(&p8);
                        ncs_dec_skip_space(i_ub, 4);
 
+                       if(immdevt->type == IMMD_EVT_ND2D_IMPLSET_REQ_2) {
+                               IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 
4);
+                               immdevt->info.impl_set.r.oi_timeout = 
ncs_decode_32bit(&p8);
+                               ncs_dec_skip_space(i_ub, 4);
+                       } else {
+                               immdevt->info.impl_set.r.oi_timeout = 0;
+                       }
+
                        /*intentional fall through - decode impl_id */
                case IMMD_EVT_ND2D_DISCARD_IMPL:        /*Internal discard 
implementer message */
 
@@ -4603,6 +4642,7 @@ static uint32_t immsv_evt_dec_toplevel(N
                        break;
 
                case IMMND_EVT_A2ND_OI_IMPL_SET:        /* 
saImmOiImplementerSet */
+               case IMMND_EVT_A2ND_OI_IMPL_SET_2:      /* 
saImmOiImplementerSet */
                        IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 8);
                        immndevt->info.implSet.client_hdl = 
ncs_decode_64bit(&p8);
                        ncs_dec_skip_space(i_ub, 8);
@@ -4613,6 +4653,11 @@ static uint32_t immsv_evt_dec_toplevel(N
                        /* immndevt->info.implSet.impl_name.buf decoded by 
sublevel */
 
                        /*skip scope & impl_id */
+                       if(immndevt->type == IMMND_EVT_A2ND_OI_IMPL_SET_2) {
+                               IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 
4);
+                               immndevt->info.implSet.oi_timeout = 
ncs_decode_32bit(&p8);
+                               ncs_dec_skip_space(i_ub, 4);
+                       }
                        break;
 
                        /*Fevs call IMMA->IMMD->IMMNDs have to suport non-flat 
encoding */
@@ -5132,6 +5177,7 @@ static uint32_t immsv_evt_dec_toplevel(N
                        break;
 
                case IMMND_EVT_D2ND_IMPLSET_RSP:        /* Implter set reply 
from D with impl id */
+               case IMMND_EVT_D2ND_IMPLSET_RSP_2:
                        IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 8);
                        immndevt->info.implSet.client_hdl = 
ncs_decode_64bit(&p8);
                        ncs_dec_skip_space(i_ub, 8);
@@ -5148,6 +5194,12 @@ static uint32_t immsv_evt_dec_toplevel(N
                        IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 4);
                        immndevt->info.implSet.scope = ncs_decode_32bit(&p8);
                        ncs_dec_skip_space(i_ub, 4);
+
+                       if(immndevt->type == IMMND_EVT_D2ND_IMPLSET_RSP_2) {
+                               IMMSV_FLTN_SPACE_ASSERT(p8, local_data, i_ub, 
4);
+                               immndevt->info.implSet.oi_timeout = 
ncs_decode_32bit(&p8);
+                               ncs_dec_skip_space(i_ub, 4);
+                       }
                        break;
 
                case IMMND_EVT_D2ND_DISCARD_IMPL:       /* Discard implementer 
broadcast to NDs */
diff --git a/osaf/libs/common/immsv/include/immsv_evt.h 
b/osaf/libs/common/immsv/include/immsv_evt.h
--- a/osaf/libs/common/immsv/include/immsv_evt.h
+++ b/osaf/libs/common/immsv/include/immsv_evt.h
@@ -205,6 +205,8 @@ typedef enum immnd_evt_type {
 
        IMMND_EVT_A2ND_ACCESSOR_GET = 94,       /* saImmOmAccessorGet_2 */
        IMMND_EVT_A2ND_CCB_VALIDATE = 95,       /* saImmOmCcbValidate */
+       IMMND_EVT_A2ND_OI_IMPL_SET_2 = 96,      /* saImmOiImplementerSet */
+       IMMND_EVT_D2ND_IMPLSET_RSP_2 = 97,              /* Implementer set 
reply from D with impl id */
 
        IMMND_EVT_MAX
 } IMMND_EVT_TYPE;
@@ -251,6 +253,8 @@ typedef enum immd_evt_type {
 
        IMMD_EVT_ND2D_2PBE_PRELOAD = 26, /* Redundant PBE preload stats to 
IMMD. */
 
+       IMMD_EVT_ND2D_IMPLSET_REQ_2 = 27, /* OiImplementerSet */
+
        IMMD_EVT_MAX
 } IMMD_EVT_TYPE;
 /* Make sure the string array in immsv_evt.c matches the IMMD_EVT_TYPE enum. */
diff --git a/osaf/libs/common/immsv/include/immsv_evt_model.h 
b/osaf/libs/common/immsv/include/immsv_evt_model.h
--- a/osaf/libs/common/immsv/include/immsv_evt_model.h
+++ b/osaf/libs/common/immsv/include/immsv_evt_model.h
@@ -274,6 +274,7 @@ extern "C" {
                IMMSV_OCTET_STRING impl_name;   /*and className and objName */
                SaUint32T impl_id;
                SaUint32T scope;        /*Only for obj impl set/rel */
+               SaUint32T oi_timeout;   /* Timeout for OI callbacks */
        } IMMSV_OI_IMPLSET_REQ;
 
        typedef struct immsv_oi_ccb_upcall_rsp {
diff --git a/osaf/services/saf/immsv/immd/immd_evt.c 
b/osaf/services/saf/immsv/immd/immd_evt.c
--- a/osaf/services/saf/immsv/immd/immd_evt.c
+++ b/osaf/services/saf/immsv/immd/immd_evt.c
@@ -133,6 +133,7 @@ void immd_process_evt(void)
                rc = immd_evt_proc_adminit_req(cb, &evt->info.immd, 
&evt->sinfo);
                break;
        case IMMD_EVT_ND2D_IMPLSET_REQ:
+       case IMMD_EVT_ND2D_IMPLSET_REQ_2:
                rc = immd_evt_proc_impl_set_req(cb, &evt->info.immd, 
&evt->sinfo);
                break;
        case IMMD_EVT_ND2D_DISCARD_IMPL:
@@ -1766,12 +1767,18 @@ static uint32_t immd_evt_proc_impl_set_r
 
        memset(&fevs_evt, 0, sizeof(IMMSV_EVT));
        fevs_evt.type = IMMSV_EVT_TYPE_IMMND;
-       fevs_evt.info.immnd.type = IMMND_EVT_D2ND_IMPLSET_RSP;
        fevs_evt.info.immnd.info.implSet.impl_id = globalId;
        fevs_evt.info.immnd.info.implSet.impl_name.size = 
impl_req->impl_name.size;
        fevs_evt.info.immnd.info.implSet.impl_name.buf = 
impl_req->impl_name.buf;       /*Warning, borrowing pointer, dont deallocate */
        fevs_evt.info.immnd.info.implSet.client_hdl = impl_req->client_hdl;     
/*redundant */
 
+       if(evt->type == IMMD_EVT_ND2D_IMPLSET_REQ_2) {
+               fevs_evt.info.immnd.info.implSet.oi_timeout = 
impl_req->oi_timeout;
+               fevs_evt.info.immnd.type = IMMND_EVT_D2ND_IMPLSET_RSP_2;
+       } else {
+               fevs_evt.info.immnd.type = IMMND_EVT_D2ND_IMPLSET_RSP;
+       }
+
        proc_rc = ncs_enc_init_space(&uba);
        if (proc_rc != NCSCC_RC_SUCCESS) {
                LOG_WA("Failed init ubaid");
diff --git a/osaf/services/saf/immsv/immnd/ImmModel.cc 
b/osaf/services/saf/immsv/immnd/ImmModel.cc
--- a/osaf/services/saf/immsv/immnd/ImmModel.cc
+++ b/osaf/services/saf/immsv/immnd/ImmModel.cc
@@ -79,7 +79,8 @@ struct AttrInfo
 struct ImplementerInfo
 {
     ImplementerInfo():mId(0), mConn(0), mNodeId(0), mMds_dest(0LL),
-                      mAdminOpBusy(0), mDying(false), mApplier(false){}
+                      mAdminOpBusy(0), mDying(false), mApplier(false),
+                      mTimeout(DEFAULT_TIMEOUT_SEC) {}
     SaUint32T       mId;
     SaUint32T       mConn; //Current implementer, only valid on one node.
     //NULL otherwise.
@@ -89,6 +90,7 @@ struct ImplementerInfo
     unsigned int    mAdminOpBusy;
     bool            mDying;
     bool            mApplier; //This is an applier OI
+    SaUint32T        mTimeout; //OI callback timeout
 };
 
 typedef std::vector<ImplementerInfo*> ImplementerVector;
@@ -1313,7 +1315,7 @@ immModel_nextResult(IMMND_CB *cb, void* 
     IMMSV_OM_RSP_SEARCH_NEXT** rsp,
     SaUint32T* implConn, SaUint32T* implNodeId,
     struct ImmsvAttrNameList** rtAttrsToFetch,
-    MDS_DEST* implDest, SaBoolT retardSync)
+    MDS_DEST* implDest, SaBoolT retardSync, SaUint32T *oiTimeout)
 {
     AttributeList* rtAttrs = NULL;
     SaAisErrorT err = SA_AIS_OK;
@@ -1334,6 +1336,10 @@ immModel_nextResult(IMMND_CB *cb, void* 
             return SA_AIS_ERR_TRY_AGAIN;
         }
         err = ImmModel::instance(&cb->immModel)->nextSyncResult(rsp, *op);
+
+        if(oiTimeout && err == SA_AIS_OK) {
+            *oiTimeout = DEFAULT_TIMEOUT_SEC;
+        }
     } else {
         /* Reset search time */
         op->updateSearchTime();
@@ -1341,6 +1347,16 @@ immModel_nextResult(IMMND_CB *cb, void* 
         err = op->nextResult(rsp, implConn, implNodeId,
             (rtAttrsToFetch)?(&rtAttrs):NULL,
             (SaUint64T*) implDest);
+
+        if(oiTimeout && err == SA_AIS_OK) {
+            std::string objectName((*rsp)->objectName.buf, 
(*rsp)->objectName.size - 1);
+            ObjectMap::iterator omi = sObjectMap.find(objectName);
+            if(omi != sObjectMap.end()) {
+                *oiTimeout = (omi->second->mImplementer) ? 
omi->second->mImplementer->mTimeout : DEFAULT_TIMEOUT_SEC;
+            } else {
+                *oiTimeout = DEFAULT_TIMEOUT_SEC;
+            }
+        }
     }
 
     if(err != SA_AIS_OK) { return err; }
@@ -1417,9 +1433,9 @@ immModel_setAdmReqContinuation(IMMND_CB 
 
 void
 immModel_setSearchReqContinuation(IMMND_CB *cb, SaInvocationT invoc, 
-    SaUint32T reqConn)
-{
-    ImmModel::instance(&cb->immModel)->setSearchReqContinuation(invoc, 
reqConn);
+    SaUint32T reqConn, SaUint32T oiTimeout)
+{
+    ImmModel::instance(&cb->immModel)->setSearchReqContinuation(invoc, 
reqConn, oiTimeout);
 }
 
 void
@@ -1434,14 +1450,20 @@ immModel_setSearchImplContinuation(IMMND
 SaAisErrorT
 immModel_implementerSet(IMMND_CB *cb, const IMMSV_OCTET_STRING* implName,
     SaUint32T implConn, SaUint32T implNodeId,
-    SaUint32T implId, MDS_DEST mds_dest)
-{
+    SaUint32T implId, MDS_DEST mds_dest,
+    SaUint32T oiTimeout)
+{
+    if(!oiTimeout) {
+        oiTimeout = DEFAULT_TIMEOUT_SEC;
+    }
+
     return 
         ImmModel::instance(&cb->immModel)->implementerSet(implName, 
             implConn,
             implNodeId,
             implId,
-            (SaUint64T) mds_dest);
+            (SaUint64T) mds_dest,
+            oiTimeout);
 }
 
 SaAisErrorT 
@@ -10248,11 +10270,11 @@ ImmModel::setAdmReqContinuation(SaInvoca
 }
 
 void
-ImmModel::setSearchReqContinuation(SaInvocationT& saInv, SaUint32T reqConn)
-{
-    TRACE_ENTER();
-    TRACE_5("setSearchReqContinuation <%llu, %u>", saInv, reqConn);
-    sSearchReqContinuationMap[saInv] = ContinuationInfo2(reqConn, 
DEFAULT_TIMEOUT_SEC);
+ImmModel::setSearchReqContinuation(SaInvocationT& saInv, SaUint32T reqConn, 
SaUint32T oiTimeout)
+{
+    TRACE_ENTER();
+    TRACE_5("setSearchReqContinuation <%llu, %u, %usec>", saInv, reqConn, 
oiTimeout);
+    sSearchReqContinuationMap[saInv] = ContinuationInfo2(reqConn, oiTimeout);
     TRACE_LEAVE();
 }
 
@@ -11007,12 +11029,23 @@ ImmModel::getOldCriticalCcbs(IdVector& c
     *pbeConnPtr = 0;
     *pbeIdPtr = 0;
     CcbVector::iterator i;
+    CcbImplementerMap::iterator cim;
+    uint32_t max_oi_timeout;
     time_t now = time(NULL);
     osafassert(now > ((time_t) 0));
     for(i=sCcbVector.begin(); i!=sCcbVector.end(); ++i) {
+        max_oi_timeout = 0;
+        for(cim = (*i)->mImplementers.begin(); cim != 
(*i)->mImplementers.end(); ++cim) {
+            if(cim->second->mImplementer->mTimeout > max_oi_timeout) {
+                max_oi_timeout = cim->second->mImplementer->mTimeout;
+            }
+        }
+        if(!max_oi_timeout)
+            max_oi_timeout = DEFAULT_TIMEOUT_SEC;
+
         if((*i)->mState == IMM_CCB_CRITICAL && 
            (((*i)->mWaitStartTime && 
-             now - (*i)->mWaitStartTime >= DEFAULT_TIMEOUT_SEC)||/* Should be 
saImmOiTimeout*/
+             now - (*i)->mWaitStartTime >= max_oi_timeout)||/* Should be 
saImmOiTimeout*/
              (*i)->mPbeRestartId))
         {
             /* We have a critical ccb that has: timed out OR lived through a 
PBE restart.
@@ -11069,9 +11102,9 @@ ImmModel::getOldCriticalCcbs(IdVector& c
                 continue;
             } 
 
-            if((ccb->mPbeRestartId == 0) && now - ccb->mWaitStartTime < 
(DEFAULT_TIMEOUT_SEC + addSecs)) {
+            if((ccb->mPbeRestartId == 0) && now - ccb->mWaitStartTime < 
(max_oi_timeout + addSecs)) {
                 LOG_NO("Ccb %u is old, but also large (%u) will wait 
secs:%ld", ccb->mId, mutations, 
-                    (DEFAULT_TIMEOUT_SEC + addSecs) - (now - 
ccb->mWaitStartTime));
+                    (max_oi_timeout + addSecs) - (now - ccb->mWaitStartTime));
                 continue;
             }
 
@@ -11262,7 +11295,7 @@ ImmModel::cleanTheBasement(InvocVector& 
         ci2!=sSearchReqContinuationMap.end();
         ++ci2) {
         //TODO the timeout should not be hardwired, but for now it is.
-        if(now - ci2->second.mCreateTime >= DEFAULT_TIMEOUT_SEC) {
+        if(now - ci2->second.mCreateTime >= ci2->second.mTimeout) {
             TRACE_5("Timeout on Search continuation %llu", ci2->first);
             searchReqs.push_back(ci2->first);
         } 
@@ -11293,8 +11326,20 @@ ImmModel::cleanTheBasement(InvocVector& 
                 (*i3)->mId);
             TRACE("state:%u waitsart:%u PberestartId:%u",(*i3)->mState, 
                 (unsigned int) (*i3)->mWaitStartTime, (*i3)->mPbeRestartId);
+
+            CcbImplementerMap::iterator cim;
+            uint32_t max_oi_timeout = 0;
+            for(cim = (*i3)->mImplementers.begin(); cim != 
(*i3)->mImplementers.end(); ++cim) {
+                if(cim->second->mImplementer->mTimeout > max_oi_timeout) {
+                    max_oi_timeout = cim->second->mImplementer->mTimeout;
+                }
+            }
+            if(!max_oi_timeout) {
+                max_oi_timeout = DEFAULT_TIMEOUT_SEC;
+            }
+
             if(((*i3)->mWaitStartTime &&
-                (now - (*i3)->mWaitStartTime >= DEFAULT_TIMEOUT_SEC)) ||
+                (now - (*i3)->mWaitStartTime >= max_oi_timeout)) ||
                 ((*i3)->mPbeRestartId)) {
                 //TODO Timeout value should be fetched from IMM service object.
                 if((*i3)->mPbeRestartId) { 
@@ -11316,9 +11361,9 @@ ImmModel::cleanTheBasement(InvocVector& 
                     if((*i3)->mPbeRestartId) {
                         LOG_WA("Ccb: %u in critical state when PBE restarted", 
(*i3)->mId);
                         ccbsStuck=1;
-                    } else if(now - (*i3)->mWaitStartTime >= 
(DEFAULT_TIMEOUT_SEC + addSecs)){
+                    } else if(now - (*i3)->mWaitStartTime >= (max_oi_timeout + 
addSecs)){
                         LOG_WA("Timeout (%d) on transaction in critical state! 
ccb:%u", 
-                            (DEFAULT_TIMEOUT_SEC + addSecs), (*i3)->mId);
+                            (max_oi_timeout + addSecs), (*i3)->mId);
                         ccbsStuck=1;
                     }
                 } else {
@@ -11431,7 +11476,8 @@ ImmModel::implementerSet(const IMMSV_OCT
     SaUint32T conn,
     SaUint32T nodeId,
     SaUint32T implementerId,
-    SaUint64T mds_dest)
+    SaUint64T mds_dest,
+    SaUint32T oiTimeout)
 {
     SaAisErrorT err = SA_AIS_OK;
     CcbVector::iterator i;
@@ -11542,6 +11588,7 @@ ImmModel::implementerSet(const IMMSV_OCT
     info->mAdminOpBusy = 0;
     info->mMds_dest = mds_dest;
     info->mDying = false;
+    info->mTimeout = oiTimeout;
     
     if(isApplier) {
         info->mApplier = true;
diff --git a/osaf/services/saf/immsv/immnd/ImmModel.hh 
b/osaf/services/saf/immsv/immnd/ImmModel.hh
--- a/osaf/services/saf/immsv/immnd/ImmModel.hh
+++ b/osaf/services/saf/immsv/immnd/ImmModel.hh
@@ -378,7 +378,8 @@ public:
                                        SaUint32T con,
                                        SaUint32T nodeId,
                                        SaUint32T ownerId,
-                                       SaUint64T mds_dest);
+                                       SaUint64T mds_dest,
+                                       SaUint32T oiTimeout);
     
     SaAisErrorT         classImplementerSet(
                                             const struct ImmsvOiImplSetReq* 
req,
@@ -543,7 +544,8 @@ public:
                                                  SaUint32T* reqConn); //in-out?
     void              setSearchReqContinuation(
                                                SaInvocationT& inv,
-                                               SaUint32T conn);
+                                               SaUint32T conn,
+                                               SaUint32T oiTimeout);
 
     void              setAdmReqContinuation(
                                                SaInvocationT& inv,
diff --git a/osaf/services/saf/immsv/immnd/immnd_evt.c 
b/osaf/services/saf/immsv/immnd/immnd_evt.c
--- a/osaf/services/saf/immsv/immnd/immnd_evt.c
+++ b/osaf/services/saf/immsv/immnd/immnd_evt.c
@@ -447,7 +447,9 @@ uint32_t immnd_evt_destroy(IMMSV_EVT *ev
                evt->info.immnd.info.classDescr.attrDefinitions = NULL;
 
        } else if ((evt->info.immnd.type == IMMND_EVT_A2ND_OI_IMPL_SET) ||
+                  (evt->info.immnd.type == IMMND_EVT_A2ND_OI_IMPL_SET_2) ||
                   (evt->info.immnd.type == IMMND_EVT_D2ND_IMPLSET_RSP) ||
+                  (evt->info.immnd.type == IMMND_EVT_D2ND_IMPLSET_RSP_2) ||
                   (evt->info.immnd.type == IMMND_EVT_A2ND_OI_CL_IMPL_SET) ||
                   (evt->info.immnd.type == IMMND_EVT_A2ND_OI_CL_IMPL_REL) ||
                   (evt->info.immnd.type == IMMND_EVT_A2ND_OI_OBJ_IMPL_SET) ||
@@ -563,6 +565,7 @@ void immnd_process_evt(void)
                break;
 
        case IMMND_EVT_A2ND_OI_IMPL_SET:
+       case IMMND_EVT_A2ND_OI_IMPL_SET_2:
                rc = immnd_evt_proc_impl_set(cb, &evt->info.immnd, &evt->sinfo);
                break;
 
@@ -1178,7 +1181,7 @@ static uint32_t immnd_evt_proc_oi_att_pu
                if (err == SA_AIS_OK) {
                        TRACE_2("oi_att_pull_rpl searchInit returned OK, 
calling searchNext");
                        IMMSV_OM_RSP_SEARCH_NEXT *rsp = 0;
-                       err = immModel_nextResult(cb, searchOp, &rsp, NULL, 
NULL, NULL, NULL, SA_FALSE);
+                       err = immModel_nextResult(cb, searchOp, &rsp, NULL, 
NULL, NULL, NULL, SA_FALSE, NULL);
                        if (err == SA_AIS_OK) {
                                rspo->runtimeAttrs.attrValuesList = 
rsp->attrValuesList;
                                /*STEALING*/ rsp->attrValuesList = NULL;
@@ -1390,6 +1393,7 @@ static uint32_t immnd_evt_proc_search_ne
        IMMSV_OM_RSP_SEARCH_BUNDLE_NEXT bundleSearch = {0, NULL};
        int ix;
        SaBoolT isAccessor = SA_FALSE;
+       SaUint32T oiTimeout;
 
        TRACE_ENTER();
 
@@ -1434,7 +1438,7 @@ static uint32_t immnd_evt_proc_search_ne
        }
 
        error = immModel_nextResult(cb, sn->searchOp, &rsp, &implConn, 
&implNodeId, &rtAttrsToFetch,
-               &implDest, retardSync);
+               &implDest, retardSync, &oiTimeout);
        if (error != SA_AIS_OK) {
                goto agent_rsp;
        }
@@ -1520,7 +1524,7 @@ static uint32_t immnd_evt_proc_search_ne
 
                TRACE_2("SETTING SEARCH REQ CONTINUATION FOR %u|%x->%u", 
sn->searchId, implNodeId, clientId);
 
-               immModel_setSearchReqContinuation(cb, invoc, clientId);
+               immModel_setSearchReqContinuation(cb, invoc, clientId, 
oiTimeout);
 
                cl_node->tmpSinfo = *sinfo;     //TODO should be part of 
continuation?
 
@@ -1547,7 +1551,7 @@ static uint32_t immnd_evt_proc_search_ne
                                break;
 
                        err = immModel_nextResult(cb, sn->searchOp, &rsp1, 
&implConn, &implNodeId, &rtAttrs,
-                                       &implDest, retardSync);
+                                       &implDest, retardSync, NULL);
                        if(err != SA_AIS_OK) {
                                osafassert(err == SA_AIS_ERR_NOT_EXIST);
                                break;
@@ -2374,12 +2378,18 @@ static uint32_t immnd_evt_proc_impl_set(
        }
 
        send_evt.type = IMMSV_EVT_TYPE_IMMD;
-       send_evt.info.immd.type = IMMD_EVT_ND2D_IMPLSET_REQ;
        send_evt.info.immd.info.impl_set.r.client_hdl = client_hdl;
        send_evt.info.immd.info.impl_set.r.impl_name.size = 
evt->info.implSet.impl_name.size;
        send_evt.info.immd.info.impl_set.r.impl_name.buf = 
evt->info.implSet.impl_name.buf;     /*Warning re-using buffer, no copy. */
        send_evt.info.immd.info.impl_set.reply_dest = cb->immnd_mdest_id;
 
+       if(evt->type == IMMND_EVT_A2ND_OI_IMPL_SET_2) {
+               send_evt.info.immd.info.impl_set.r.oi_timeout = 
evt->info.implSet.oi_timeout;
+               send_evt.info.immd.type = IMMD_EVT_ND2D_IMPLSET_REQ_2;
+       } else {
+               send_evt.info.immd.type = IMMD_EVT_ND2D_IMPLSET_REQ;
+       }
+
        /* send the request to the IMMD, reply comes back over fevs. */
 
        rc = immnd_mds_msg_send(cb, NCSMDS_SVC_ID_IMMD, cb->immd_mdest_id, 
&send_evt);
@@ -3124,6 +3134,11 @@ static SaAisErrorT immnd_fevs_local_chec
                error = SA_AIS_ERR_LIBRARY;
                break;
 
+       case IMMND_EVT_D2ND_IMPLSET_RSP_2:
+               LOG_WA("ERR_LIBRARY: IMMND_EVT_D2ND_IMPLSET_RSP_2 can not 
arrive from client lib");
+               error = SA_AIS_ERR_LIBRARY;
+               break;
+
        case IMMND_EVT_D2ND_CCBINIT:
                LOG_WA("ERR_LIBRARY: IMMND_EVT_D2ND_CCBINIT can not arrive from 
client lib");
                error = SA_AIS_ERR_LIBRARY;
@@ -7437,7 +7452,8 @@ static uint32_t immnd_restricted_ok(IMMN
                    id == IMMND_EVT_A2ND_OI_IMPL_CLR ||
                    id == IMMND_EVT_D2ND_SYNC_FEVS_BASE ||
                    id == IMMND_EVT_A2ND_OI_OBJ_MODIFY ||
-                   id == IMMND_EVT_D2ND_IMPLSET_RSP) {
+                   id == IMMND_EVT_D2ND_IMPLSET_RSP ||
+                   id == IMMND_EVT_D2ND_IMPLSET_RSP_2) {
                        return 1;
                }
        }
@@ -7593,6 +7609,7 @@ immnd_evt_proc_fevs_dispatch(IMMND_CB *c
                break;
 
        case IMMND_EVT_D2ND_IMPLSET_RSP:
+       case IMMND_EVT_D2ND_IMPLSET_RSP_2:
                immnd_evt_proc_impl_set_rsp(cb, &frwrd_evt.info.immnd, 
originatedAtThisNd, clnt_hdl, reply_dest);
                break;
 
@@ -8997,8 +9014,15 @@ static void immnd_evt_proc_impl_set_rsp(
        nodeId = m_IMMSV_UNPACK_HANDLE_LOW(clnt_hdl);
        TRACE_2("originated here?:%u nodeId:%x conn: %u", originatedAtThisNd, 
nodeId, conn);
 
+       if(evt->type == IMMND_EVT_D2ND_IMPLSET_RSP) {
+               /* In immModel_implementerSet, 0 will be replaced with 
DEFAULT_TIMEOUT_SEC
+                * as the default value */
+               evt->info.implSet.oi_timeout = 0;
+       }
+
        err = immModel_implementerSet(cb, &(evt->info.implSet.impl_name),
-                                     (originatedAtThisNd) ? conn : 0, nodeId, 
evt->info.implSet.impl_id, reply_dest);
+                       (originatedAtThisNd) ? conn : 0, nodeId, 
evt->info.implSet.impl_id,
+                       reply_dest, evt->info.implSet.oi_timeout);
 
        if (originatedAtThisNd) {       /*Send reply to client from this ND. */
                immnd_client_node_get(cb, clnt_hdl, &cl_node);
diff --git a/osaf/services/saf/immsv/immnd/immnd_init.h 
b/osaf/services/saf/immsv/immnd/immnd_init.h
--- a/osaf/services/saf/immsv/immnd/immnd_init.h
+++ b/osaf/services/saf/immsv/immnd/immnd_init.h
@@ -199,7 +199,8 @@ extern "C" {
            immModel_nextResult(IMMND_CB *cb, void *searchOp,
                                IMMSV_OM_RSP_SEARCH_NEXT **rsp,
                                SaUint32T *implConn, SaUint32T *implNodeId,
-                               struct ImmsvAttrNameList **rtAttrsToFetch, 
MDS_DEST *implDest, SaBoolT retardSync);
+                               struct ImmsvAttrNameList **rtAttrsToFetch,
+                               MDS_DEST *implDest, SaBoolT retardSync, 
SaUint32T *oiTimeout);
 
        void immModel_deleteSearchOp(void *searchOp);
 
@@ -211,14 +212,15 @@ extern "C" {
 
        void immModel_setAdmReqContinuation(IMMND_CB *cb, SaInvocationT invoc, 
SaUint32T reqCon);
 
-       void immModel_setSearchReqContinuation(IMMND_CB *cb, SaInvocationT 
invoc, SaUint32T reqCon);
+       void immModel_setSearchReqContinuation(IMMND_CB *cb, SaInvocationT 
invoc, SaUint32T reqCon, SaUint32T oiTimeout);
 
        void immModel_setSearchImplContinuation(IMMND_CB *cb, SaUint32T 
searchId,
                                                SaUint32T requestnodeId, 
MDS_DEST reply_dest);
 
        SaAisErrorT
            immModel_implementerSet(IMMND_CB *cb, const IMMSV_OCTET_STRING 
*implName,
-                                   SaUint32T implConn, SaUint32T implNodeId, 
SaUint32T implId, MDS_DEST mds_dest);
+                                   SaUint32T implConn, SaUint32T implNodeId, 
SaUint32T implId,
+                                   MDS_DEST mds_dest, SaUint32T oiTimeout);
 
        SaAisErrorT
            immModel_implementerClear(IMMND_CB *cb, const struct 
ImmsvOiImplSetReq *req,

------------------------------------------------------------------------------
Is your legacy SCM system holding you back? Join Perforce May 7 to find out:
&#149; 3 signs your SCM is hindering your productivity
&#149; Requirements for releasing software faster
&#149; Expert tips and advice for migrating your SCM now
http://p.sf.net/sfu/perforce
_______________________________________________
Opensaf-devel mailing list
Opensaf-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opensaf-devel

Reply via email to