DSMCC  17.9.0
 All Data Structures Files Functions Typedefs
loadMgr.c
Go to the documentation of this file.
1 /*******************************************************************************
2  * Copyright © 2014 The DTVKit Open Software Foundation Ltd (www.dtvkit.org)
3  * Copyright © 2004 Ocean Blue Software Ltd
4  * Copyright © 2001 Koninklijke Philips Electronics N.V
5  *
6  * This file is part of a DTVKit Software Component
7  * You are permitted to copy, modify or distribute this file subject to the terms
8  * of the DTVKit 1.0 Licence which can be found in licence.txt or at www.dtvkit.org
9  *
10  * THIS CODE AND INFORMATION ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
11  * EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES
12  * OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR PURPOSE.
13  *
14  * If you or your organisation is not a member of DTVKit then you have access
15  * to this source code outside of the terms of the licence agreement
16  * and you are expected to delete this and any associated files immediately.
17  * Further information on DTVKit, membership and terms can be found at www.dtvkit.org
18  *******************************************************************************/
26 /*---includes for this file--------------------------------------------------*/
27 #include <string.h>
28 #include "clDsmSystem.h"
29 #include "loadMgr.h"
30 
31 #include "sectionFilter.h"
32 #include "cacheMgr.h"
33 #include "module.h"
34 #include "moduleData.h"
35 #include "moduleDecompress.h"
36 #include "object.h"
37 #include "dataCarousel.h"
38 #include "dsmObject.h"
39 #include "clDsmUtils.h"
40 #include "cldsmcc.h"
41 #include "defMemUtilsMgd.h" /* -- Default mem type for module */
42 #include "sectionTimer.h"
43 
44 
45 /*---constant definitions for this file--------------------------------------*/
46 
47 /*---local typedef structs for this file-------------------------------------*/
48 
49 typedef struct LiteOptionObject_tag LiteOptionObject_t, *pLiteOptionObject_t;
50 
51 struct LiteOptionObject_tag
52 {
53  S_LLObject llData[NUM_LITE_OBJECT_LOAD_LIST];
54  U8BIT name[257];
55  P_LoadRequest pLoadRequest;
56 };
57 
58 /*---local (static) variable declarations for this file----------------------*/
59 
60 /****************************
61 * LOCAL FUNCTION PROTOTYPES *
62 *****************************/
63 
64 static E_DscError ProgressLoadRequest( P_DsmCoreInst idp, P_LoadRequest pLoadRequest );
65 
66 static E_DscError LoadStalledModule( P_DsmCoreInst idp, P_LoadRequest pLoadRequest );
67 
68 static E_DscError UpdateModuleLoadRequests( P_DsmCoreInst idp, P_Module pModule );
69 
70 static E_DscError PreFetchRelativeDirObj( P_DsmCoreInst idp,
71  P_LoadRequest pCurrLR, P_ObjectLocation pLocation,
72  P_DeliveryParaTap pTap, U32BIT timeout );
73 
74 static E_DscError PreFetchRelativeNonDirObj( P_DsmCoreInst idp,
75  P_LoadRequest pCurrLR, P_ObjectLocation pLocation,
76  P_DeliveryParaTap pTap, U32BIT timeout );
77 
78 static E_DscError PreFetchNewDirsAndDIIsFromLoadedDir( P_DsmCoreInst idp,
79  P_LoadRequest pLoadRequest );
80 
81 static void UpdateModuleCachingNoFlush( P_DsmCoreInst idp, P_LoadRequest pLoadRequest );
82 
83 static void ObjectLoadFinalise( P_DsmCoreInst idp, P_LoadRequest pLoadRequest );
84 
85 static void PreFetchDirLoadFinalise( P_DsmCoreInst idp, P_LoadRequest pLoadRequest );
86 
87 static E_DscError lmLiteOptionsObjectOnModuleUpdate(P_DsmCoreInst idp, U8BIT *name,
88  P_ObjectCarousel pCurrOC, P_Module pLoadedModule, P_LoadRequest pLoadRequest );
89 
90 /*---------------------------- Exported Functions ----------------------------*/
91 
92 /* /////////////////////////////////////////////////////////////////////////////
93 // lmObjectLoadCreate
94 //
95 // If objectCarousel SRG is loaded (check OC info)
96 // Create loadRequest
97 // Initialise loadRequest
98 // Store loadRequest target type and set finalise func
99 // Store path and timeout in loadRequest
100 // Store SRG info from OC in loadRequest
101 // Advance loadRequest as far as poss. with currently cached data
102 // [loadRequestAdvance]
103 // If loadRequest stalled on a module
104 // create module load [LoadStalledModule]
105 // Assign o/p loadRequest handle
106 // Return OK to caller
107 // Else
108 // Set o/p loadRequest handle to NULL
109 // Return SRG_NOT_LOADED_ERROR to caller
110 // Endif
111 //
113 static E_DscError ObjectLoadCreate( P_DsmCoreInst idp, P_ObjectCarousel pOC,
114  U8BIT *path, U32BIT timeout, H_ObjUserData pUserData, U32BIT sizeOfUserData,
115  P_DsmObject pDsmObject, P_LoadRequest *ppLoadRequest )
116 {
117  E_DscError err;
118  U8BIT *pRemaining;
119  U32BIT pathlen;
120  P_LoadRequest pLoadRequest;
121 
122  pathlen = strlen((char *)path);
123 
124  err = DSC_LoadRsqtCreate( idp, sizeof(S_LoadRequest) + sizeOfUserData + pathlen + 1,
125  TT_GEN_OBJECT, pDsmObject, (F_LoadFinalise)ObjectLoadFinalise, (P_RootLoadRqst *)&pLoadRequest );
126  if (!err)
127  {
128  pLoadRequest->pObjCarousel = pOC;
129  pLoadRequest->rlr.cachingRules = pDsmObject->cachingRules;
130 
131  pRemaining = (U8BIT *)(pLoadRequest + 1);
132  pLoadRequest->rlr.usrRef = pRemaining;
133  memcpy(pRemaining, pUserData, sizeOfUserData);
134  pRemaining += sizeOfUserData;
135  pLoadRequest->pRemainingPath = pRemaining;
136  memcpy(pRemaining, path, pathlen);
137  }
138  *ppLoadRequest = pLoadRequest;
139  return err;
140 }
141 
142 static E_DscError LoadRequestOnSrg( P_DsmCoreInst idp, P_ObjectCarousel pOC,
143  P_LoadRequest pLoadRequest )
144 {
145  E_DscError err;
146  P_Module pModule;
147 
148  /* -- NB. SRG DC & module would normally exist but may
149  -- (temporarily) have been deleted due to update
150  -- or cache priority fromStream (CCP0) being set
151  -- on an object in the same module as the SRG */
152  pModule = DSC_ObjCrslSrgModule(pOC);
153  pLoadRequest->pDataCarousel = DSC_RootCrslFirstDataCarousel(&pOC->root);
154  if (pModule == NULL)
155  {
156  DBG1(DD_LM,"No Module on carousel %p",pOC)
157  err = CLDSM_OK;
158  pLoadRequest->rlr.status = LRS_STALLED_SRG_MODULE;
159  }
160  else
161  {
162  pLoadRequest->pModule = pModule;
163  if (pOC->srgObjectInfo.objectKind != SRG_STR)
164  {
165  pLoadRequest->rlr.status = LRS_STALLED_SRG_MODULE;
166  }
167  /* SRG module is in the process of being (or already is) updated/re-loaded
168  * ie. transparent caching (when turbo-caching enabled). SRG data carousel must also be assigned
169  */
170  /* If SRG module is now cached (loaded) Setup and advance load */
171  if (pModule->status == MS_CACHED)
172  {
173  pLoadRequest->pDataCarousel = LLParent(pModule, DC_MODULE_LIST);
174  /* -- NB. pSrgModule must be closed since it can get deleted/unloaded */
175  err = ProgressLoadRequest( idp, pLoadRequest );
176  }
177  else
178  {
179  DBG1(DD_LM,"Module %p, status %u",pModule,pModule->status)
180  err = CLDSM_OK;
181  }
182  }
183  return err;
184 }
185 
186 static void LoadRequestHandleCaching( P_DsmCoreInst idp, P_ObjectCarousel pOC,
187  P_LoadRequest pLoadRequest )
188 {
189  P_Module pCurrModule;
190  BOOLEAN loadRequestsOnModule;
191 
192  dsmAssert((pLoadRequest->pModule != NULL));
193 
194  /* If this gets called during the notify callback of another loadRequest on the same module
195  * there may still be outstanding loads on this module that have not yet been processed.
196  * Only update the cache status here when/if there are no other outstanding load requests on this module.
197  */
198  pCurrModule = pLoadRequest->pModule;
199  dsmAssert((pCurrModule->status == MS_CACHED));
200  dsmAssert((pCurrModule->hModuleData != NULL));
201  /* -- TODO: Handle prioritisation of all caching rule settings */
202  /* -- If new caching rules have fromStream set they override any previous
203  -- caching rules for module */
204  if (pLoadRequest->rlr.cachingRules < pCurrModule->cachingRules)
205  {
206  pCurrModule->cachingRules = pLoadRequest->rlr.cachingRules;
207  }
208 
209  dsmAssert((pCurrModule->status == MS_CACHED));
210  loadRequestsOnModule = (pCurrModule->llcLoadRequests == NULL) ? FALSE : TRUE;
211 
212  if (loadRequestsOnModule == FALSE)
213  {
214  /* Update cache status of module according to module's current caching rules.
215  * Don't flush parent DC since we will immediately reload module if it is destroyed. */
216  UpdateModuleCachingNoFlush( idp, pLoadRequest );
217  } /* else - there are further requests on the module so don't update module cache status now */
218 }
219 
220 /* /////////////////////////////////////////////////////////////////////////////
221 // lmRequestObjectLoad
222 //
223 // If objectCarousel SRG is loaded (check OC info)
224 // Create loadRequest
225 // Initialise loadRequest
226 // Store loadRequest target type and set finalise func
227 // Store path and timeout in loadRequest
228 // Store SRG info from OC in loadRequest
229 // Advance loadRequest as far as poss. with currently cached data
230 // [loadRequestAdvance]
231 // If loadRequest stalled on a module
232 // create module load [LoadStalledModule]
233 // Assign o/p loadRequest handle
234 // Return OK to caller
235 // Else
236 // Set o/p loadRequest handle to NULL
237 // Return SRG_NOT_LOADED_ERROR to caller
238 // Endif
239 //
241 E_DscError lmRequestObjectLoad( P_DsmCoreInst idp, P_ObjectCarousel pOC,
242  U8BIT *path, U32BIT timeout,
243  H_ObjUserData pUserData, U32BIT sizeOfUserData,
244  P_DsmObject pDsmObject,
245  P_LoadRequest *ppLoadRequest )
246 {
247  P_LoadRequest pLoadRequest;
248  E_DscError err = CLDSM_OK;
249 
250  dsmDP3(("lmRequestObjectLoad()\n"));
251  dsmAssert((idp != NULL));
252  dsmAssert((pOC != NULL));
253  dsmAssert((path != NULL));
254  dsmAssert((ppLoadRequest != NULL));
255 
256  switch (pOC->root.status)
257  {
258  case RCS_PENDING_BOOTINFO:
259  case RCS_BOOTING:
260  err = ObjectLoadCreate( idp, pOC, path, timeout, pUserData, sizeOfUserData,
261  pDsmObject, ppLoadRequest );
262  if (err == CLDSM_OK)
263  {
264  pLoadRequest = *ppLoadRequest;
265  pLoadRequest->rlr.status = LRS_STALLED_SRG_MODULE;
266  }
267  break;
268 
269  case RCS_BOOTED:
270  case RCS_LOADED:
271  err = ObjectLoadCreate( idp, pOC, path, timeout, pUserData, sizeOfUserData,
272  pDsmObject, ppLoadRequest );
273  if (err == CLDSM_OK)
274  {
275  pLoadRequest = *ppLoadRequest;
276  pLoadRequest->objectLocation = pOC->srgObjLoc;
277  pLoadRequest->tap = pOC->srgTap;
278  err = LoadRequestOnSrg( idp, pOC, pLoadRequest );
279  if (err == CLDSM_OK)
280  {
281  if (pLoadRequest->rlr.status == LRS_LOADED)
282  {
283  LoadRequestHandleCaching( idp, pOC, pLoadRequest );
284  }
285  if ((pLoadRequest->rlr.status == LRS_STALLED_SRG_MODULE) ||
286  (pLoadRequest->rlr.status == LRS_STALLED_MODULE))
287  {
288  err = LoadStalledModule( idp, pLoadRequest );
289  }
290  }
291  if (err)
292  {
293  /* -- Error so destroy/free allocated memory objects */
294  DSC_LoadRsqtDestroy( idp, (P_RootLoadRqst)pLoadRequest );
295  *ppLoadRequest = NULL;
296  }
297  }
298  break;
299 
300  case RCS_LOAD_FAILED:
301  err = CLDSM_ERR_CAROUSEL_LOAD_FAILED;
302  break;
303 
304  default:
305  dsmDP1(("ERROR: Illegal carousel status = %u\n", pOC->root.status));
306  dsmAssert((0));
307  err = CLDSM_ERR_INTERNAL;
308  break;
309  }
310 
311  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: lmRequestObjectLoad: %u\n", err)));
312  return err;
313 }
314 
315 /* /////////////////////////////////////////////////////////////////////////////
316 // lmPrefetchObjectLoad
317 //
318 // If objectCarousel SRG is loaded (check OC info)
319 // Create loadRequest
320 // Initialise loadRequest
321 // Store loadRequest target type and set finalise func
322 // Store path and timeout in loadRequest
323 // Store SRG info from OC in loadRequest
324 // Advance loadRequest as far as poss. with currently cached data
325 // [loadRequestAdvance]
326 // If loadRequest stalled on a module
327 // create module load [LoadStalledModule]
328 // Assign o/p loadRequest handle
329 // Return OK to caller
330 // Else
331 // Set o/p loadRequest handle to NULL
332 // Return SRG_NOT_LOADED_ERROR to caller
333 // Endif
334 //
336 E_DscError lmPrefetchObjectLoad( P_DsmCoreInst idp,
337  P_ObjectCarousel pOC, U8BIT *path, U32BIT timeout,
338  P_LoadRequest *ppLoadRequest )
339 {
340  E_DscError err;
341  U8BIT *pRemaining;
342  U32BIT pathlen;
343  P_LoadRequest pLoadRequest;
344 
345  dsmDP3(("lmPrefetchObjectLoad()\n"));
346  dsmAssert((idp != NULL));
347  dsmAssert((pOC != NULL));
348  dsmAssert((path != NULL));
349  dsmAssert((ppLoadRequest != NULL));
350 
351  switch (pOC->root.status)
352  {
353  case RCS_PENDING_BOOTINFO:
354  case RCS_BOOTING:
355  err = CLDSM_ERR_CAROUSEL_NOT_BOOTED;
356  break;
357 
358  case RCS_BOOTED:
359  case RCS_LOADED:
360  pathlen = strlen((char *)path);
361  err = DSC_LoadRsqtCreate( idp, sizeof(S_LoadRequest), TT_GEN_OBJECT, pOC, NULL, (P_RootLoadRqst *)&pLoadRequest );
362  if (!err)
363  {
364  pLoadRequest->pObjCarousel = pOC;
365 
366  pRemaining = (U8BIT *)(pLoadRequest + 1);
367  pLoadRequest->pRemainingPath = pRemaining;
368  memcpy(pRemaining, path, pathlen);
369 
370  pLoadRequest->objectLocation = pOC->srgObjLoc;
371  pLoadRequest->tap = pOC->srgTap;
372 
373  err = LoadRequestOnSrg( idp, pOC, pLoadRequest );
374  if (err == CLDSM_OK)
375  {
376  if ((pLoadRequest->rlr.status == LRS_STALLED_SRG_MODULE) ||
377  (pLoadRequest->rlr.status == LRS_STALLED_MODULE))
378  {
379  err = LoadStalledModule( idp, pLoadRequest );
380  }
381  }
382  if (err)
383  {
384  DSC_LoadRsqtDestroy( idp, (P_RootLoadRqst)pLoadRequest );
385  pLoadRequest = NULL;
386  }
387  }
388  break;
389 
390  case RCS_LOAD_FAILED:
391  err = CLDSM_ERR_CAROUSEL_LOAD_FAILED;
392  break;
393 
394  default:
395  dsmDP1(("ERROR: Illegal carousel status = %u\n", pOC->root.status));
396  dsmAssert((0));
397  err = CLDSM_ERR_INTERNAL;
398  break;
399  }
400 
401  *ppLoadRequest = pLoadRequest;
402 
403  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: lmPrefetchObjectLoad: %u\n", err)));
404  return err;
405 }
406 
407 /* /////////////////////////////////////////////////////////////////////////////
408 // lmLoadDestroy
409 //
411 void lmLoadDestroy( P_DsmCoreInst idp, P_LoadRequest pLoadRequest )
412 {
413  DSC_LoadRsqtDestroy( idp, (P_RootLoadRqst)pLoadRequest );
414 }
415 
416 /* /////////////////////////////////////////////////////////////////////////////
417 // lmGetObjectLoadState
418 //
419 // Determine if an object (ie. object's module) is currently 'loaded' (ie. in
420 // the cache)
421 //
423 E_DscError lmGetObjectLoadState( P_DsmCoreInst idp,
424  P_ObjectCarousel pOC, U8BIT *path, P_Module *ppModule )
425 {
426  E_DscError err = CLDSM_OK;
427  U8BIT *pRemaining;
428  U32BIT pathlen;
429  P_LoadRequest pLoadRequest;
430  P_Module pModule;
431 
432  dsmDP3(("lmGetObjectLoadState()\n"));
433  dsmAssert((idp != NULL));
434  dsmAssert((pOC != NULL));
435  dsmAssert((path != NULL));
436  dsmAssert((ppModule != NULL));
437 
438  *ppModule = NULL;
439 
440  switch (pOC->root.status)
441  {
442  case RCS_PENDING_BOOTINFO:
443  case RCS_BOOTING:
444  err = CLDSM_ERR_CAROUSEL_NOT_BOOTED;
445  break;
446 
447  case RCS_BOOTED:
448  /* -- Object cannot be loaded */
449  break;
450 
451  case RCS_LOADED:
452  /* -- Check SRG object is currently loaded (ie. not in process of
453  -- being updated) */
454  if (DSC_ObjCrslSrgObjectLoaded(pOC))
455  {
456  pathlen = strlen((char *)path);
457  err = DSC_LoadRsqtCreate( idp, sizeof(S_LoadRequest) + pathlen + 1, TT_TMP_OBJECT, pOC, NULL, (P_RootLoadRqst *)&pLoadRequest );
458  if (!err)
459  {
460  pLoadRequest->pObjCarousel = pOC;
461 
462  pRemaining = (U8BIT *)(pLoadRequest + 1);
463  pLoadRequest->pRemainingPath = pRemaining;
464  memcpy(pRemaining, path, pathlen);
465 
466  pLoadRequest->objectLocation = pOC->srgObjLoc;
467  pLoadRequest->tap = pOC->srgTap;
468 
469  /* -- SRG module and DC must both be assigned */
470  dsmAssert((DSC_ObjCrslSrgModule(pOC) != NULL));
471 
472  pLoadRequest->pDataCarousel = DSC_RootCrslFirstDataCarousel(&pOC->root);
473  pLoadRequest->pModule = DSC_ObjCrslSrgModule(pOC);
474 
475  err = ProgressLoadRequest( idp, pLoadRequest );
476  if (!err)
477  {
478  pModule = pLoadRequest->pModule;
479  switch (pLoadRequest->rlr.status)
480  {
481  case LRS_LOADED:
482  *ppModule = pModule;
483  break;
484  case LRS_STALLED_MODULE:
485  {
486  if (pModule != NULL)
487  {
488  if (pModule->status == MS_ACQ_FAILED)
489  {
490  /*
491  -- This (transient) state only
492  -- occurs when turbo-caching is
493  -- enabled and decompress has failed
494  -- on a module that was cached
495  -- compressed (ie. not in use)
496  --
497  -- In this case, attempt to
498  -- re-acquire module (low priority
499  -- since not in use).
500  */
501  dsmAssert((idp->setup.turboCaching == TRUE));
502  pModule->status = MS_PENDING_DDB;
503  err = DSC_ModuleAcquireStart( idp, pModule, SF_PRIORITY_LOW );
504  }
505  }
506  break;
507  }
508  default:
509  /* -- Any other states - do nothing */
510  break;
511  }
512  }
513  /* -- Free the allocated memory (finished with) */
514  DSC_LoadRsqtDestroy( idp, (P_RootLoadRqst)pLoadRequest );
515  }
516  }
517  break;
518 
519  case RCS_LOAD_FAILED:
520  err = CLDSM_ERR_CAROUSEL_LOAD_FAILED;
521  break;
522 
523  default:
524  /* -- Illegal status */
525  dsmDP1(("ERROR: Illegal carousel status = %u\n", pOC->root.status));
526  dsmAssert((0));
527  err = CLDSM_ERR_INTERNAL;
528  break;
529  }
530 
531  DEBUG_CHK( err == CLDSM_OK, dsmDP1(("ERROR: lmGetObjectLoadState: %u\n", err)));
532  dsmDP3(("exit lmGetObjectLoadState -> rtn: %u\n", err));
533  return err;
534 }
535 
536 /* /////////////////////////////////////////////////////////////////////////////
537 // lmUpdateCarouselSRGInfo
538 //
540 E_DscError lmUpdateCarouselSRGInfo( P_DsmCoreInst idp,
541  P_ObjectCarousel pOC, P_DeliveryParaTap pSrgTap, P_ObjectLocation pSrgLocn )
542 {
543  P_LoadRequest pLoadRequest;
544  E_DscError err = CLDSM_OK;
545 
546  dsmDP3(("lmUpdateCarouselSRGInfo()\n"));
547  dsmAssert((idp != NULL));
548  dsmAssert((pOC != NULL));
549  dsmAssert((pSrgTap != NULL));
550  dsmAssert((pSrgLocn != NULL));
551 
552  /*
553  -- DSI section filter is finished with so stop it (also Nulls ref in OC).
554  */
555 
556  /* AMCarousel MONITORING => Do not STOP section filtering */
557  dsmAssert((pOC->root.pDsiSf));
558 
559 #ifdef DSI_TIMEOUT_SUPPORT
560  /* stop DSI timer */
561  sectionTimerRemove(idp, pOC->root.pDsiSf);
562 #endif /* DSI_TIMEOUT_SUPPORT */
563 
564  if (pOC->root.status == RCS_BOOTING)
565  {
566  DBGLOG(DD_OC, "DSI acquired carouselId = %u\n", pOC->root.rcid);
567 
568  pOC->srgObjLoc = *pSrgLocn;
569  pOC->srgTap = *pSrgTap;
570  pOC->root.status = RCS_BOOTED;
571 
572  dsmAssert((pOC->root.pLoadRqst != NULL));
573  pLoadRequest = (P_LoadRequest)pOC->root.pLoadRqst;
574 
575  /* -- These should not be assigned since they cannot exist
576  -- when this is executed */
577  dsmAssert((pLoadRequest->pDataCarousel == NULL));
578  dsmAssert((pLoadRequest->pModule == NULL));
579 
580  pLoadRequest->objectLocation = *pSrgLocn;
581  pLoadRequest->tap = *pSrgTap;
582  pLoadRequest->rlr.status = LRS_STALLED_SRG_MODULE;
583 
584  err = LoadStalledModule( idp, pLoadRequest );
585  if (err)
586  {
587  if (err == CLDSM_ERR_LOAD_FAILED)
588  {
589  /* -- Do not want to return this error from this function since
590  -- client is notified of failure via Load Finalise function */
591  err = CLDSM_OK;
592  }
593 
594  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
595 
596  /* -- NB. hOC must be closed when making this call
597  -- since it may get unloaded from notify callback */
598  DSC_LoadRsqtFinalise( idp, (P_RootLoadRqst)pLoadRequest );
599  }
600  else
601  {
602  /* -- NB. hOC must be closed when making this call
603  -- since it may get unloaded from notify callback */
604  if (pLoadRequest->rlr.finalise)
605  {
606  pLoadRequest->rlr.finalise( idp, (P_RootLoadRqst)pLoadRequest );
607  }
608  /* -- NB. SRG load request not completed yet so don't destroy here */
609  }
610  }
611 
612  DEBUG_CHK( err == CLDSM_OK,
613  dsmDP1(("ERROR: lmUpdateCarouselSRGInfo: %u\n", err)));
614  dsmDP3(("exit lmUpdateCarouselSRGInfo -> rtn: %u\n", err));
615  return err;
616 }
617 
618 static void lmLiteOptionsModuleUpdate( P_DsmCoreInst idp, P_Module pModule )
619 {
620  P_DataCarousel pDC;
621  P_ObjectCarousel pOC;
622  pLiteOptionObject_t pLiteObjFromList, pLiteObjFromListToDelete;
623  ListId_t listId;
624 
625  pDC = (P_DataCarousel)LLParent( pModule, MODULE_ACQUIRE_LIST );
626  if (memValidate(pDC))
627  {
628  pOC = LLParent(pDC, OC_DATA_CAROUSEL_LIST);
629  }
630  else
631  {
632  pOC = NULL;
633  }
634  if (memValidate(pOC) && TRUE == pOC->bOCLiteOptionsObjectProcessing)
635  {
636  pLiteObjFromListToDelete = NULL;
637  /* Get listId and first OC in list from Control block */
638  listId = LListId( pOC->llcOcPostponedLiteObjectLoads );
639  pLiteObjFromList = LLHead( pOC->llcOcPostponedLiteObjectLoads );
640  dsmDP2(("LITE list %u => handle = %#p\n", listId, pLiteObjFromList));
641 
642  while (pLiteObjFromList != NULL)
643  {
644  dsmDP2(("CALL liteOptionsObjectHandle: name = %s pRequest = %#p\n",
645  pLiteObjFromList->name, pLiteObjFromList->pLoadRequest));
646 
647  lmLiteOptionsObjectOnModuleUpdate( idp, pLiteObjFromList->name,
648  pOC, pModule, pLiteObjFromList->pLoadRequest );
649 
650  if (LRS_LITE_OPTIONS_LOADED == pLiteObjFromList->pLoadRequest->rlr.status)
651  {
652  dsmDP2(("LITE_OPTIONS: Finalise object loading\n"));
653  ObjectLoadFinalise(idp, pLiteObjFromList->pLoadRequest);
654  pLiteObjFromListToDelete = pLiteObjFromList;
655  }
656  pLiteObjFromList = LLNext( pLiteObjFromList, listId );
657  /* remove current from list */
658  if (NULL != pLiteObjFromListToDelete)
659  {
660  LLRemove( pLiteObjFromListToDelete, OC_LITE_OBJECT_LOAD_LIST );
661  pLiteObjFromListToDelete = NULL;
662  }
663  }
664  }
665 }
666 
667 /* /////////////////////////////////////////////////////////////////////////////
668 // lmUpdateModule
669 //
670 // Called when a new module build is completed to update any waiting
671 // load requests
672 //
674 E_DscError lmUpdateModule( P_DsmCoreInst idp, P_Module pModule )
675 {
676  E_DscError err;
677 
678  dsmDP3(("lmUpdateModule()\n"));
679  dsmAssert((idp != NULL));
680  dsmAssert((pModule != NULL));
681  dsmAssert((pModule->status == MS_CACHED));
682  dsmAssert((pModule->loadedCount == 0));
683 
684  dsmDP2(("lmUpdateModule: loaded ModuleId=%u, version=%d\n", pModule->moduleInfo.moduleId, pModule->moduleInfo.version));
685 
686  lmLiteOptionsModuleUpdate( idp, pModule );
687 
688  if (pModule->llcLoadRequests)
689  {
690  /* -- By default, add new module to head of module priority list (this
691  -- may subsequently be changed within UpdateModuleLoadRequests) */
692  LLInsertHead( idp->llcModulePriority, pModule );
693  err = UpdateModuleLoadRequests( idp, pModule );
694  }
695  else
696  {
697  /* -- This is either a module version update or new module
698  -- pre-fetch */
699  /* -- If module is not already in priority list (eg. when a new
700  -- module pre-fetch), add to priority list tail */
701  if (!LLCheckInListCtrl( idp->llcModulePriority, pModule ))
702  {
703  /* -- Add new module to tail of priority list */
704  LLInsertTail( idp->llcModulePriority, pModule );
705  }
706  err = CLDSM_OK;
707  }
708  DBGERRCHK(err)
709  return err;
710 }
711 
712 /* /////////////////////////////////////////////////////////////////////////////
713 // lmStopModuleLoadRequest
714 //
715 // If the loadRequest is attached to a module
716 // Abort and destroy loadRequest
717 //
718 // If there are no more outstanding loadRequests on this module
719 // If turboCaching enabled
720 // continue acquiring module
721 // Else
722 // destroy module
723 //
725 void lmStopModuleLoadRequest( P_DsmCoreInst idp, P_LoadRequest pLoadRequest )
726 {
727  P_ObjectCarousel pOC;
728  P_Module pModule;
729  BOOLEAN inList;
730  BOOLEAN listEmpty;
731 
732  dsmDP3(("lmStopModuleLoadRequest()\n"));
733  dsmAssert((idp != NULL));
734  dsmAssert((pLoadRequest != NULL));
735 
736  inList = LLCheckInListId( MODULE_LOAD_REQUEST_LIST, pLoadRequest );
737  if (!inList)
738  {
739  pLiteOptionObject_t pLiteObjFromList;
740  ListId_t listId;
741 
742  pOC = pLoadRequest->pObjCarousel;
743 
744  if (pOC->bOCLiteOptionsObjectProcessing)
745  {
746  /* Get listId and first OC in list from Control block */
747  listId = LListId( pOC->llcOcPostponedLiteObjectLoads );
748  pLiteObjFromList = LLHead( pOC->llcOcPostponedLiteObjectLoads );
749  dsmDP2(("LITE list %u => handle = %#p\n", listId, pLiteObjFromList));
750 
751  while (pLiteObjFromList)
752  {
753  if (pLiteObjFromList->pLoadRequest == pLoadRequest)
754  {
755  DSC_LoadRsqtFinalise( idp, (P_RootLoadRqst)pLoadRequest );
756  break;
757  }
758  pLiteObjFromList = LLNext( pLiteObjFromList, listId );
759  }
760  }
761  else
762  {
763  /* - Load request not attached to a module (error - DO NOT ignore) */
764  DSC_LoadRsqtAbort( idp, &pLoadRequest->rlr );
765  }
766  }
767  else
768  {
769  /* -- Remove load request from module load request list */
770  dsmAssert((LLParent(pLoadRequest, MODULE_LOAD_REQUEST_LIST) == pLoadRequest->pModule));
771  listEmpty = DSC_ModuleRemoveLoadRequest(idp, pLoadRequest);
772 
773  /* -- Save the module location handles and target kind */
774  pModule = (P_Module)pLoadRequest->pModule;
775 
776  /* -- NB. Handles should never be NULL when loadRequest on a module */
777  dsmAssert((pLoadRequest->pObjCarousel));
778  dsmAssert((pLoadRequest->pDataCarousel));
779  dsmAssert((pModule));
780 
781  /* -- Abort/destroy the loadRequest */
782  DSC_LoadRsqtAbort( idp, &pLoadRequest->rlr );
783 
784  /*
785  -- If there are no other loadRequests waiting for module
786  --
787  -- If this is a carousel load (or turboCaching disabled)
788  -- Destroy the module (and any parent DC if empty)
789  -- else
790  -- Continue acquiring module (as pre-fetch)
791  */
792  if (listEmpty)
793  {
794  /* -- There are no other loadRequests on module */
795 
796  /* -- Module load should always be 'in progress' */
797  dsmAssert(((pModule->status == MS_PENDING_INFO) ||
798  (pModule->status == MS_PENDING_DDB) ||
799  (pModule->status == MS_BUILDING)));
800 
801  if ((pLoadRequest->rlr.targetKind == TT_CAROUSEL) ||
802  (idp->setup.turboCaching == FALSE) ||
803  (idp->cacheFull == TRUE))
804  {
805  /* Destroy the module and destroy parent DC if now empty */
806  DSC_ModuleDeleteDcTidyUp( idp, pModule );
807  }
808  /* else - Continue acquiring (pre-fetching) module
809  NB. Cannot re-set priority of DDB filters to low
810  so no need to update filter priority */
811  }
812  /* else - There are still active load requests on module */
813  }
814 
815  dsmDP3(("exit lmStopModuleLoadRequest\n"));
816 }
817 
818 /* /////////////////////////////////////////////////////////////////////////////
819 // lmSetObjectModuleLoaded
820 //
822 void lmSetObjectModuleLoaded( P_DsmCoreInst idp, P_Module pModule )
823 {
824  dsmAssert((idp != NULL));
825  dsmAssert((pModule != NULL));
826  dsmAssert((pModule->status == MS_CACHED));
827  dsmAssert((pModule->hModuleData != NULL));
828 
829  pModule->loadedCount++;
830 
831  if (pModule->loadedCount == 1)
832  {
833  /* -- This is first object loaded in this module */
834 
835  /* -- Remove module from priority list */
836  LLRemove( pModule, MODULE_PRIORITY_LIST );
837  /* -- Add module to loaded list */
838  LLInsertHead( idp->llcLoadedModules, pModule );
839  }
840 }
841 
842 /* /////////////////////////////////////////////////////////////////////////////
843 // lmSetObjectModuleUnloaded
844 //
846 void lmSetObjectModuleUnloaded( P_DsmCoreInst idp, P_Module pModule )
847 {
848  dsmAssert((idp != NULL));
849  dsmAssert((pModule != NULL));
850 
851  dsmAssert((pModule->loadedCount > 0));
852  pModule->loadedCount--;
853  if (pModule->loadedCount == 0)
854  {
855  if (pModule->status == MS_EXPIRED)
856  {
857 #ifndef NDEBUG
858  {
859  BOOLEAN inList;
860 
861  inList = LLCheckInListCtrl( idp->llcExpiredModules, pModule );
862  dsmAssert((inList == TRUE));
863  }
864 #endif
865 
866  /* TODO: use llRemoveCtrl here (when implemented) */
867  LLRemove( pModule, MODULE_DELETE_LIST );
868  DSC_ModuleDestroy( idp, pModule );
869  }
870  else if (pModule->status == MS_CACHED)
871  {
872  /* -- Remove module from loaded list */
873  LLRemove( pModule, MODULE_LOADED_LIST );
874  /* -- Add/promote module to head of priority list */
875  LLInsertHead( idp->llcModulePriority, pModule );
876  }
877  /* else if (pModule->status == MS_PENDING_DDB) then reloading for CCP0
878  * so do not move from loaded list to priority list - avoids being purged by cache manager */
879  }
880 }
881 
882 void lmObjCarouselTimeout( P_DsmCoreInst idp, P_ObjectCarousel pOC )
883 {
884  if (pOC->root.pLoadRqst)
885  {
886  P_LoadRequest pLoadRequest = (P_LoadRequest)pOC->root.pLoadRqst;
887  if (LLCheckInListId(MODULE_LOAD_REQUEST_LIST, pLoadRequest))
888  {
889  dsmAssert((LLParent(pLoadRequest, MODULE_LOAD_REQUEST_LIST) == pLoadRequest->pModule));
890  DSC_ModuleRemoveLoadRequest(idp, pLoadRequest);
891  }
892  }
893 }
894 
895 /* /////////////////////////////////////////////////////////////////////////////
896 // abortLoadRequestsOnModuleTimeout
897 //
899 void lmAbortLoadRequestsOnModuleTimeout( P_DsmCoreInst idp, P_Module pModule)
900 {
901  P_LoadRequest pLoadRequest;
902  BOOLEAN listEmpty;
903 
904  dsmDP2(("lmAbortLoadRequestsOnModuleTimeout()\n"));
905  dsmAssert((idp != NULL));
906  dsmAssert((pModule != NULL));
907  if (pModule->llcLoadRequests != NULL)
908  {
909  pLoadRequest = LLHead( pModule->llcLoadRequests );
910  while (pLoadRequest != NULL)
911  {
912  dsmAssert((LLParent(pLoadRequest, MODULE_LOAD_REQUEST_LIST) == pLoadRequest->pModule));
913  listEmpty = DSC_ModuleRemoveLoadRequest(idp, pLoadRequest);
914 
915  pLoadRequest->rlr.status = LRS_ABORTED_TIMEOUT;
916  DSC_LoadRsqtAbort( idp, &pLoadRequest->rlr );
917 
918  if (listEmpty)
919  break;
920 
921  pLoadRequest = LLHead( pModule->llcLoadRequests );
922  }
923  }
924 }
925 
926 /*------------------------------ Local Functions -----------------------------*/
927 
928 
929 /* /////////////////////////////////////////////////////////////////////////////
930 // LoadStalledModule
931 //
932 // Load the module which a load request has stalled on.
933 //
935 static E_DscError LoadStalledModule( P_DsmCoreInst idp, P_LoadRequest pLoadRequest )
936 {
937  P_ObjectCarousel pOC;
938  P_DataCarousel pDC;
939  P_Module pModule;
940  E_DscError err = CLDSM_OK;
941  E_SFPriority sfPriority;
942 
943  dsmDP3(("LoadStalledModule()\n"));
944  dsmAssert((idp != NULL));
945  dsmAssert((pLoadRequest != NULL));
946 
947  dsmAssert(((pLoadRequest->rlr.status == LRS_STALLED_MODULE) ||
948  (pLoadRequest->rlr.status == LRS_STALLED_SRG_MODULE)));
949 
950  pOC = pLoadRequest->pObjCarousel;
951  dsmAssert((pOC != NULL));
952  pDC = pLoadRequest->pDataCarousel;
953  pModule = pLoadRequest->pModule;
954 
955  if (pDC != NULL)
956  {
957  dsmAssert(((pLoadRequest->tap.transactionId & TRANSACTION_ID_IDENT_MASK) == pDC->dataCarouselId));
958  if (pModule == NULL)
959  {
960  err = DSC_ModuleCreate( idp, pLoadRequest->objectLocation.moduleId, &pModule );
961  if (!err)
962  {
963  LLInsertTail( pDC->llcDcModules, pModule );
964  err = DSC_DataCrslNewModuleLoad( idp, pDC, pModule );
965  }
966  else /* error in DSC_ModuleCreate */
967  {
968  if (!LLCount(pDC->llcDcModules))
969  {
970  DSC_DataCrslDestroy( idp, pDC );
971  }
972  }
973  }
974  /* else - module already exists */
975  }
976  else
977  {
978  /* -- Data carousel does not exist */
979  err = DSC_DataCrslCreate( idp, &pOC->root, &(pLoadRequest->tap), &pDC );
980  if (!err)
981  {
982  err = DSC_ModuleCreate( idp, pLoadRequest->objectLocation.moduleId, &pModule );
983  if (!err)
984  {
985  LLInsertTail( pDC->llcDcModules, pModule );
986  err = DSC_DataCrslNewModuleLoad( idp, pDC, pModule );
987  }
988  else
989  {
990  /* -- Error creating module so destroy new data carousel also */
991  DSC_DataCrslDestroy( idp, pDC );
992  }
993  }
994  /* else - error in dataCarousel create */
995  }
996 
997  if (!err)
998  {
999  pLoadRequest->pDataCarousel = pDC;
1000  pLoadRequest->pModule = pModule;
1001 
1002  /* -- Module should not be cached, expired or loaded */
1003  /* dsmAssert((pModule->status != MS_CACHED)); */
1004  dsmAssert((pModule->status != MS_INITIAL));
1005  dsmAssert((pModule->status != MS_EXPIRED));
1006 
1007  err = DSC_ModuleAddLoadRequest( idp, pModule, pLoadRequest );
1008  if (err)
1009  {
1010  DSC_ModuleDeleteDcTidyUp( idp, pModule );
1011  }
1012  else
1013  {
1014  switch (pModule->status)
1015  {
1016  case MS_ACQ_ABORTED:
1017  /* Module was previously aborted due multiple decompression
1018  -- failures. This is new load request so try to acquire again. */
1019  pModule->decompressFailureCount = 0;
1020  /*fall thro*/
1021  case MS_ACQ_FAILED:
1022  /* -- Module had a decompression failure. Acquire again */
1023  pModule->status = MS_PENDING_DDB;
1024  /*fall thro*/
1025  case MS_PENDING_DDB:
1026  case MS_BUILDING:
1027  {
1028  /* -- We are ready to acquire (or are already acquiring) this module */
1029  /* -- Determine section filter priority */
1030  sfPriority = DSC_LoadRsqtPriority((P_RootLoadRqst)pLoadRequest);
1031  /* NB. If we are already acquiring module, DSC_ModuleAcquireStart
1032  will only update/check section filter priority. */
1033  err = DSC_ModuleAcquireStart( idp, pModule, sfPriority );
1034  if (err)
1035  {
1036  /* -- Failure to start (or update priority of) section filter so abort module */
1037  DSC_ModuleDeleteDcTidyUp( idp, pModule );
1038  }
1039  break;
1040  }
1041  default: /*MS_CACHED or MS_EXPIRED*/
1042  break;
1043  }
1044  }
1045  }
1046  DEBUG_CHK( err == CLDSM_OK,
1047  dsmDP1(("ERROR: LoadStalledModule: %u\n", err)));
1048  dsmDP3(("exit LoadStalledModule -> rtn: %u\n", err));
1049  return err;
1050 }
1051 
1052 /* /////////////////////////////////////////////////////////////////////////////
1053 // loadRequestStepPath
1054 //
1056 static void loadRequestStepPath( P_LoadRequest pLoadRequest, U8BIT *nextPathElement )
1057 {
1058  U8BIT *pRemainingPath;
1059  U8BIT *currPath;
1060  U8BIT *pFirstTokenEnd;
1061  U32BIT remainingLength;
1062 
1063  dsmDP3(("loadRequestStepPath()\n"));
1064  dsmAssert((pLoadRequest != NULL));
1065  dsmAssert((nextPathElement != NULL));
1066 
1067  pRemainingPath = pLoadRequest->pRemainingPath;
1068 
1069  currPath = pRemainingPath + pLoadRequest->remainingPathOffset;
1070  remainingLength = strlen((char *)currPath );
1071  if (remainingLength > 0)
1072  {
1073  pFirstTokenEnd = (U8BIT *)strchr((char *)currPath, PATH_SEPERATOR_CHAR );
1074 
1075  if (pFirstTokenEnd == NULL)
1076  {
1077  strcpy((char *)nextPathElement, (char *)currPath );
1078  pLoadRequest->remainingPathOffset += remainingLength;
1079  }
1080  else
1081  {
1082  remainingLength = pFirstTokenEnd - currPath;
1083  strncpy((char *)nextPathElement, (char *)currPath, remainingLength );
1084  nextPathElement[remainingLength] = '\0';
1085 
1086  /* Skip to the position *after* the separator */
1087  pLoadRequest->remainingPathOffset += remainingLength + 1;
1088  }
1089  }
1090  else
1091  {
1092  *nextPathElement = '\0';
1093  }
1094 
1095  dsmDP3(("exit loadRequestStepPath\n"));
1096 }
1097 
1098 E_DscError lmLiteOptionsObjectHandle( P_DsmCoreInst idp, U8BIT *name, P_LoadRequest pLoadRequest )
1099 {
1100  P_ObjectCarousel pCurrOC = NULL;
1101  P_Module pCurrModule = NULL;
1102  P_DataCarousel pCurrDC = NULL;
1103  MemPtr mpModuleData, mpObjectData;
1104  E_DscError err = CLDSM_OK;
1105  U16BIT service_id, temp16;
1106  U32BIT moduleDataSize, carousel_id, temp32, objectLength, i;
1107  P_Module pModuleFromList = NULL;
1108  ListId_t moduleListId;
1109  BOOLEAN found;
1110  S32BIT objOffset;
1111  ObjectDataInfo_t objInfo = { {0, {0}}, 0, 0, 0, 0, 0, 0};
1112  /*MemPos currPos,endPos;*/
1113  BOOLEAN valid;
1114  MemPtr mpBindingData;
1115  S_ObjectLocation objectLocation;
1116  S_DeliveryParaTap objectTap;
1117  BOOLEAN bDoLoadObject = TRUE;
1118  pLiteOptionObject_t pLiteObject;
1119 
1120  dsmDP4(("LITE_OPTIONS: lmLiteOptionsObjectHandle\n"));
1121 
1122  dsmDP4(("LITE_OPTIONS: Process LITE OPTION for object = %#p\n",
1123  pLoadRequest->rlr.target));
1124 
1125  carousel_id = (U32BIT)pLoadRequest->objectLocation.dvbCarouselNSAPaddress[2];
1126  carousel_id <<= 24;
1127  carousel_id &= 0xFF000000;
1128  temp32 = (U32BIT)pLoadRequest->objectLocation.dvbCarouselNSAPaddress[3];
1129  carousel_id |= ((temp32 << 16) & 0x00FF0000);
1130  temp32 = (U32BIT)pLoadRequest->objectLocation.dvbCarouselNSAPaddress[4];
1131  carousel_id |= ((temp32 << 8) & 0x0000FF00);
1132  temp32 = (U32BIT)pLoadRequest->objectLocation.dvbCarouselNSAPaddress[5];
1133  carousel_id |= (temp32 & 0x000000FF);
1134 
1135  service_id = pLoadRequest->objectLocation.dvbCarouselNSAPaddress[14];
1136  service_id <<= 8;
1137  service_id &= 0xFF00;
1138  temp16 = pLoadRequest->objectLocation.dvbCarouselNSAPaddress[15];
1139  service_id |= (temp16 & 0x00FF);
1140 
1141  pCurrOC = (P_ObjectCarousel)DSC_RootCrslListFindById( idp->llcRootCarousels, service_id, carousel_id );
1142 
1143  if (NULL == pCurrOC)
1144  {
1145  dsmDP1(("LITE_OPTIONS: Carousel %u not loaded\n", carousel_id));
1146 
1147  err = CDSM_LoadCarousel(idp, service_id, carousel_id,
1148  SIQUERY_CAROUSEL, (H_DsmCarousel *)&pCurrOC);
1149 
1150  pLoadRequest->rlr.status = LRS_LITE_OPTIONS_PENDING;
1151  pLoadRequest->pObjCarousel = pCurrOC;
1152 
1153  if (!err && pCurrOC && pLoadRequest->rlr.targetKind != TT_TMP_OBJECT)
1154  {
1155  pLiteObject = (pLiteOptionObject_t)DSC_CmMemGet( idp, sizeof(LiteOptionObject_t) );
1156  if (!pLiteObject)
1157  {
1158  err = CLDSM_ERR_MEM_HEAP_FULL;
1159  }
1160  else
1161  {
1162  err = CLDSM_OK;
1163  dsmDP2(("LITE_OPTIONS: STORE POSTPONED LITE LOAD: pLiteObject = %#p\n", pLiteObject));
1164  llLinkInit( pLiteObject->llData, NUM_LITE_OBJECT_LOAD_LIST );
1165  pLiteObject->pLoadRequest = pLoadRequest;
1166  strncpy((char *)pLiteObject->name, (char *)name, 257);
1167 
1168  /* Store request to be managed when carousel Load will be completed */
1169  LLInsertHead( pCurrOC->llcOcPostponedLiteObjectLoads, pLiteObject );
1170 
1171  /* Tag carousel as loaded for lite Otpions object */
1172  pCurrOC->bOCLiteOptionsObjectProcessing = TRUE;
1173  }
1174  }
1175  }
1176  else
1177  {
1178  dsmDP3(("LITE_OPTIONS: Carousel %u load on going, status:%u\n",
1179  pCurrOC->carouselId,
1180  pCurrOC->root.status));
1181 
1182  if (RCS_LOADED != pCurrOC->root.status)
1183  {
1184  if (pLoadRequest->rlr.targetKind != TT_TMP_OBJECT)
1185  {
1186  pLiteObject = (pLiteOptionObject_t)DSC_CmMemGet( idp, sizeof(LiteOptionObject_t) );
1187  if (!pLiteObject)
1188  {
1189  err = CLDSM_ERR_MEM_HEAP_FULL;
1190  }
1191  else
1192  {
1193  err = CLDSM_OK;
1194  memset(pLiteObject, 0, sizeof(LiteOptionObject_t));
1195  llLinkInit( pLiteObject->llData, NUM_LITE_OBJECT_LOAD_LIST);
1196 
1197  pLiteObject->pLoadRequest = pLoadRequest;
1198  strncpy((char *)pLiteObject->name, (char *)name, 257);
1199 
1200  LLInsertHead( pCurrOC->llcOcPostponedLiteObjectLoads, pLiteObject );
1201  }
1202  }
1203 
1204  /* carousel not completely loaded => so object loading is set to PENDING */
1205  pLoadRequest->rlr.status = LRS_LITE_OPTIONS_PENDING;
1206  pLoadRequest->pObjCarousel = pCurrOC;
1207  bDoLoadObject = FALSE;
1208  }
1209 
1210  if (TRUE == bDoLoadObject)
1211  {
1212  objInfo = pCurrOC->srgObjectInfo;
1213 
1214  /* RETRIEVE object in SRG INFO to get moduleId */
1215  pCurrModule = DSC_ObjCrslSrgModule(pCurrOC);
1216 
1217  moduleDataSize = pCurrModule->moduleInfo.originalSize;
1218 
1219  MEMPTR_SEQ_OPEN( MEM_CONTEXT, moduleDataPtr(pCurrModule->hModuleData), 0,
1220  moduleDataSize, FALSE, mpModuleData );
1221 
1222  if (moduleDataFindObject( pCurrModule->hModuleData, moduleDataSize,
1223  &(objInfo.objectKey), &mpObjectData ))
1224  {
1225  valid = objectDataGetInfo( mpObjectData, &objInfo );
1226 
1227  pCurrDC = LLParent(pCurrModule, DC_MODULE_LIST);
1228 
1229  found = odDirFindBinding( mpObjectData, &objInfo, name, &mpBindingData );
1230 
1231  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pCurrModule->hModuleData, mpModuleData );
1232 
1233  if (found)
1234  {
1235  valid = odDirGetBindingInfo( mpBindingData, &objectLocation, &objectTap );
1236  if (valid)
1237  {
1238  /* go through all MODULES */
1239 
1240  /* Get listId and first module in list from Control block */
1241  moduleListId = LListId( pCurrDC->llcDcModules );
1242  pModuleFromList = LLHead( pCurrDC->llcDcModules );
1243 
1244  /* Go through each module in list until the one with a matching moduleId
1245  is found */
1246  while (pModuleFromList)
1247  {
1248  moduleDataSize = pModuleFromList->moduleInfo.originalSize;
1249 
1250  if (pModuleFromList->moduleInfo.moduleId == objectLocation.moduleId)
1251  {
1252  MEMPTR_SEQ_OPEN( MEM_CONTEXT, moduleDataPtr(pCurrModule->hModuleData), 0,
1253  moduleDataSize, FALSE, mpModuleData );
1254 
1255  MEMPTR_OPEN( mpModuleData, mpObjectData );
1256 
1257  /*GET_POS( mpObjectData, currPos );
1258  *endPos = currPos + moduleDataSize;*/
1259 
1260  /* COPY objectkey retrieved in SRG */
1261  objInfo.objectKey.length = objectLocation.objectKey.length;
1262  for (i = 0; i < objectLocation.objectKey.length; i++)
1263  {
1264  objInfo.objectKey.data[i] = objectLocation.objectKey.data[i];
1265  }
1266 
1267  if (moduleDataFindObject( pCurrModule->hModuleData, moduleDataSize,
1268  &(objInfo.objectKey), &mpObjectData ))
1269  {
1270  dsmDP3(("LITE_OPTIONS: object path:%s found\n", name));
1271 
1272  objectDataGetInfo(mpObjectData, &objInfo);
1273 
1274  MEMPTR_GET_DIFF( mpModuleData, mpObjectData, objOffset);
1275 
1276  objectDataGetKeyAndLen( mpObjectData,
1277  &objInfo.objectKey, &objectLength );
1278 
1279  /* COPY object info to output */
1280  pLoadRequest->targetObjectOffset = (U32BIT) objOffset;
1281  pLoadRequest->targetObjectInfo = objInfo;
1282  pLoadRequest->pModule = pModuleFromList;
1283  pLoadRequest->pObjCarousel = pCurrOC;
1284  pLoadRequest->rlr.status = LRS_LITE_OPTIONS_LOADED;
1285  }
1286  }
1287 
1288  pModuleFromList = LLNext( pModuleFromList, moduleListId );
1289  }
1290 
1291  MEMPTR_CLOSE( mpObjectData );
1292  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pCurrModule->hModuleData, mpModuleData );
1293  }
1294  }
1295  }
1296  }
1297  }
1298 
1299  dsmDP4(("exit lmLiteOptionsObjectHandle err:%u reqStatus:%u\n", err, pLoadRequest->rlr.status));
1300  return err;
1301 }
1302 
1303 E_DscError lmLiteOptionsObjectOnModuleUpdate(P_DsmCoreInst idp, U8BIT *name,
1304  P_ObjectCarousel pCurrOC, P_Module pLoadedModule, P_LoadRequest pLoadRequest )
1305 {
1306  P_Module pSrgModule = NULL;
1307  MemPtr mpModuleData, mpObjectData;
1308  E_DscError err = CLDSM_OK;
1309  U32BIT moduleDataSize, objectLength, i;
1310  BOOLEAN found;
1311  S32BIT objOffset;
1312  ObjectDataInfo_t objInfo = { {0, {0}}, 0, 0, 0, 0, 0, 0};
1313  /*MemPos currPos,endPos;*/
1314  BOOLEAN valid;
1315  MemPtr mpBindingData;
1316  S_ObjectLocation objectLocation;
1317  S_DeliveryParaTap objectTap;
1318 
1319  dsmDP4(("LITE_OPTIONS: lmLiteOptionsObjectOnModuleUpdate\n"));
1320 
1321  dsmDP4(("LITE_OPTIONS: Process LITE OPTION for object = %#p path:%s\n",
1322  pLoadRequest->rlr.target, name));
1323 
1324  if ((NULL != pCurrOC) && (NULL != pLoadedModule))
1325  {
1326  dsmDP3(("LITE_OPTIONS: Carousel %u load on going, status:%u\n",
1327  pCurrOC->carouselId,
1328  pCurrOC->root.status));
1329 
1330  if (DSC_ObjCrslSrgObjectLoaded(pCurrOC))
1331  {
1332  if ((RCS_LOADED == pCurrOC->root.status) || (RCS_BOOTED == pCurrOC->root.status))
1333  {
1334  /* look for object in SRG info to get moduleId and objectKey */
1335  objInfo = pCurrOC->srgObjectInfo;
1336  pSrgModule = DSC_ObjCrslSrgModule(pCurrOC);
1337 
1338  moduleDataSize = pSrgModule->moduleInfo.originalSize;
1339 
1340  MEMPTR_SEQ_OPEN( MEM_CONTEXT, moduleDataPtr(pSrgModule->hModuleData), 0,
1341  moduleDataSize, FALSE, mpModuleData );
1342 
1343  if (moduleDataFindObject( pSrgModule->hModuleData, moduleDataSize,
1344  &(objInfo.objectKey), &mpObjectData))
1345  {
1346  valid = objectDataGetInfo( mpObjectData, &objInfo );
1347 
1348  found = odDirFindBinding( mpObjectData, &objInfo,
1349  name, &mpBindingData );
1350 
1351 
1352  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pSrgModule->hModuleData, mpModuleData );
1353 
1354  if (found)
1355  {
1356  valid = odDirGetBindingInfo( mpBindingData,
1357  &objectLocation,
1358  &objectTap );
1359 
1360  dsmDP4(("LITE_OPTIONS: name %s FOUND in SRG modid = %u\n",
1361  name, objectLocation.moduleId));
1362 
1363  if ((objectLocation.moduleId == pLoadedModule->moduleInfo.moduleId) && (valid))
1364  {
1365  moduleDataSize = pLoadedModule->moduleInfo.originalSize;
1366 
1367  MEMPTR_SEQ_OPEN( MEM_CONTEXT, moduleDataPtr(pLoadedModule->hModuleData), 0,
1368  moduleDataSize, FALSE, mpModuleData );
1369 
1370  MEMPTR_OPEN( mpModuleData, mpObjectData );
1371 
1372  /*GET_POS( mpObjectData, currPos );
1373  *endPos = currPos + moduleDataSize;*/
1374 
1375  objInfo.objectKey.length = objectLocation.objectKey.length;
1376 
1377  for (i = 0; i < objectLocation.objectKey.length; i++)
1378  {
1379  objInfo.objectKey.data[i] = objectLocation.objectKey.data[i];
1380  }
1381 
1382  if (moduleDataFindObject( pLoadedModule->hModuleData, moduleDataSize,
1383  &(objInfo.objectKey), &mpObjectData ))
1384  {
1385  objectDataGetInfo(mpObjectData, &objInfo);
1386 
1387  MEMPTR_GET_DIFF( mpModuleData, mpObjectData, objOffset);
1388 
1389  objectDataGetKeyAndLen( mpObjectData,
1390  &objInfo.objectKey, &objectLength );
1391 
1392  pLoadRequest->targetObjectOffset = (U32BIT) objOffset;
1393  pLoadRequest->targetObjectInfo = objInfo;
1394  pLoadRequest->pModule = pLoadedModule;
1395  pLoadRequest->pObjCarousel = pCurrOC;
1396  pLoadRequest->rlr.status = LRS_LITE_OPTIONS_LOADED;
1397  }
1398 
1399  MEMPTR_CLOSE( mpObjectData );
1400  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pLoadedModule->hModuleData, mpModuleData );
1401  }
1402  }
1403  }
1404  }
1405  }
1406  else
1407  {
1408  dsmDP2(("LITE_OPTIONS : abort temporarly object load SRG info not loaded !!\n"));
1409  }
1410  }
1411 
1412  return err;
1413 }
1414 
1415 /* /////////////////////////////////////////////////////////////////////////////
1416 // ProgressLoadRequest
1417 //
1419 static E_DscError ProgressLoadRequest( P_DsmCoreInst idp, P_LoadRequest pLoadRequest )
1420 {
1421 // MemHandle hCurrOC = NULL;
1422  P_ObjectCarousel pCurrOC = NULL;
1423  P_Module pCurrModule = NULL;
1424  P_DataCarousel pCurrDC = NULL;
1425  P_DataCarousel pNextDC = NULL;
1426  P_Module pNextModule = NULL;
1427  BOOLEAN progressLoad = FALSE;
1428  BOOLEAN processCurrObj = FALSE;
1429  BOOLEAN found = FALSE;
1430  BOOLEAN valid = FALSE;
1431  ObjectDataInfo_t objInf = { {0, {0}}, 0, 0, 0, 0, 0, 0};
1432  U32BIT moduleDataSize;
1433  S32BIT objOffset;
1434  U8BIT nextPathElement[MAX_OBJ_NAME_SIZE];
1435  MemPtr mpModuleData;
1436  MemPtr mpObjectData;
1437  MemPtr mpBindingData;
1438  E_DscError err = CLDSM_OK;
1439 
1440  dsmDP3(("ProgressLoadRequest()\n"));
1441  dsmAssert((idp != NULL));
1442  dsmAssert((pLoadRequest != NULL));
1443  dsmAssert(((pLoadRequest->rlr.status == LRS_INITIAL) ||
1444  (pLoadRequest->rlr.status == LRS_STALLED_MODULE) ||
1445  (pLoadRequest->rlr.status == LRS_STALLED_SRG_MODULE)));
1446 
1447  do
1448  {
1449  progressLoad = FALSE;
1450  processCurrObj = FALSE;
1451 
1452  if (pCurrModule != pLoadRequest->pModule)
1453  {
1454  /* -- This is a 'new' (cached) module so ensure it is decompressed */
1455  pNextModule = pLoadRequest->pModule;
1456 
1457  /* -- Must be cached ! */
1458  dsmAssert((pNextModule->status == MS_CACHED));
1459 
1460  /* -- If module is not yet decompressed then decompress it.
1461  -- NB. Module must be closed since it can get deleted/unloaded. */
1462  if (pNextModule->hModuleData == NULL)
1463  {
1464  err = DSC_ModuleDecompress( idp, pNextModule );
1465  if (err == CLDSM_ERR_END_OF_DATA)
1466  {
1467  /* Retry */
1468  err = CLDSM_OK;
1469  if ((pLoadRequest->rlr.status == LRS_INITIAL) &&
1470  (pLoadRequest->rlr.targetKind & TT_GEN_OBJECT))
1471  {
1472  /*
1473  -- Load is now stalled on SRG module.
1474  -- NB. For internal (relative) pre-fetches the
1475  -- initial module always starts decompressed so
1476  -- this code should only get executed on client
1477  -- requested loads.
1478  */
1479  pLoadRequest->rlr.status = LRS_STALLED_SRG_MODULE;
1480  }
1481  /* else - don't change current load request status */
1482  break; /* -- EXIT LOOP */
1483  }
1484  else if (err)
1485  {
1486  /* -- Error decompressing module so abort load request */
1487  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1488  break; /* -- EXIT LOOP */
1489  }
1490  /* else - decompress successful so continue */
1491  }
1492  /* else - module not compressed so continue */
1493  }
1494  /* else - we have already used this module (ie. it must be decompressed)
1495  so continue */
1496 
1497  pCurrModule = pLoadRequest->pModule;
1498  pCurrDC = pLoadRequest->pDataCarousel;
1499  pCurrOC = pLoadRequest->pObjCarousel;
1500 
1501  moduleDataSize = pCurrModule->moduleInfo.originalSize;
1502 
1503  MEMPTR_SEQ_OPEN( MEM_CONTEXT, moduleDataPtr(pCurrModule->hModuleData), 0,
1504  moduleDataSize, FALSE, mpModuleData );
1505  MEMPTR_OPEN( mpModuleData, mpObjectData );
1506 
1507  if (pLoadRequest->rlr.status == LRS_INITIAL)
1508  {
1509  switch (pLoadRequest->rlr.targetKind)
1510  {
1511  case TT_TMP_OBJECT:
1512  case TT_GEN_OBJECT:
1513  /*
1514  -- This is initial SRG access of object load so we can
1515  -- read current object details from the SRG object
1516  -- info store in OC
1517  */
1518 
1519  /* -- SRG module and DC must be assigned and
1520  -- SRG object loaded */
1521  dsmAssert((DSC_ObjCrslSrgModule(pCurrOC) != NULL));
1522  dsmAssert((pCurrOC->srgObjectInfo.objectKind == SRG_STR));
1523 
1524  objOffset = pCurrOC->srgObjectOffset;
1525  SET_POS_REL( mpObjectData, objOffset );
1526  objInf = pCurrOC->srgObjectInfo;
1527 
1528  pLoadRequest->rlr.status = LRS_STALLED_MODULE;
1529  processCurrObj = TRUE;
1530  break;
1531 
1532  case TT_PREFETCH_DIR_OBJ:
1533  case TT_PREFETCH_NON_DIR_OBJ:
1534  /* -- This is the start of an internal (relative) prefetch
1535  -- so we do not need to access current object */
1536  pLoadRequest->rlr.status = LRS_STALLED_MODULE;
1537  progressLoad = TRUE;
1538  break;
1539 
1540  default:
1541  dsmDP1(("ERROR: Load request - invalid initial target kind: %u\n",
1542  pLoadRequest->rlr.targetKind));
1543  dsmAssert((0));
1544 
1545  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1546  err = CLDSM_ERR_INTERNAL;
1547  break;
1548  }
1549  }
1550  else
1551  {
1552  /* -- Load request is stalled on current (SRG or other) module */
1553 
1554  /* -- Get object details from current module data */
1555 
1556  if (moduleDataFindObject( pCurrModule->hModuleData, moduleDataSize,
1557  &(pLoadRequest->objectLocation.objectKey), &mpObjectData ))
1558  {
1559  valid = objectDataGetInfo( mpObjectData, &objInf );
1560  if (valid)
1561  {
1562  /*
1563  -- NB. Don't change status here since later we need to test
1564  -- whether load is/was stalled on SRG or other module
1565  */
1566  processCurrObj = TRUE;
1567  }
1568  else
1569  {
1570  dsmDP1(("DATA ERROR: Load request aborted - object not found\n"));
1571  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1572  }
1573  }
1574  else
1575  {
1576  dsmDP1(("DATA ERROR: Load request aborted - object invalid\n"));
1577  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1578  }
1579  }
1580 
1581 
1582  if (processCurrObj)
1583  {
1584  if (pLoadRequest->rlr.status == LRS_STALLED_SRG_MODULE)
1585  {
1586  /*
1587  -- NB. This can be executed on a carousel/SRG load and
1588  -- also on an object load that was waiting for the
1589  -- SRG module (either initially after carousel boot or if
1590  -- the SRG module was (temporarily) deleted due to update).
1591  */
1592 
1593  /* -- Check if SRG object info is already assigned (ie. from
1594  -- previously processed load request) */
1595 
1596  if (!pCurrOC->srgObjectInfo.objectKind)
1597  {
1598  MEMPTR_GET_DIFF( mpModuleData, mpObjectData, objOffset );
1599  dsmAssert((objOffset >= 0));
1600 
1601  /* -- SRG module and DC must be assigned */
1602  dsmAssert((DSC_ObjCrslSrgModule(pCurrOC) != NULL));
1603  dsmAssert((objInf.objectKind == SRG_STR));
1604 
1605  pCurrOC->srgObjectOffset = (U32BIT) objOffset;
1606  pCurrOC->srgObjectInfo = objInf;
1607  }
1608  }
1609 
1610  if (pLoadRequest->pRemainingPath == NULL ||
1611  pLoadRequest->pRemainingPath[pLoadRequest->remainingPathOffset] == 0)
1612  {
1613  /* -- Load request has no path so it must now be complete */
1614 
1615  pLoadRequest->rlr.status = LRS_LOADED;
1616  }
1617  else
1618  {
1619  /* -- This is an object load with a path */
1620 
1621  if ((objInf.objectKind == DIR_STR) ||
1622  (objInf.objectKind == SRG_STR))
1623  {
1624  /* -- Current object is a 'directory' so determine
1625  -- next item in path (if any) */
1626 
1627  loadRequestStepPath( pLoadRequest, nextPathElement );
1628 
1629  if (*nextPathElement != '\0')
1630  {
1631  MEMPTR_OPEN( mpObjectData, mpBindingData );
1632 
1633  found = odDirFindBinding( mpObjectData, &objInf,
1634  nextPathElement, &mpBindingData );
1635 
1636 
1637  if (found)
1638  {
1639  valid = odDirGetBindingInfo( mpBindingData,
1640  &pLoadRequest->objectLocation,
1641  &pLoadRequest->tap );
1642 
1643  if (valid)
1644  {
1645  if (pLoadRequest->objectLocation.uiBindingTag == TAG_LITE_OPTIONS)
1646  {
1647  err = lmLiteOptionsObjectHandle(idp, nextPathElement, pLoadRequest);
1648  return err;
1649  }
1650 
1651 
1652  /* -- Load request should be progressed */
1653  progressLoad = TRUE;
1654 
1655  /* -- Check Carousel ID of objectLocation
1656  -- matches current Carousel ID */
1657  /*
1658  -- NB. L2 check since this should be correct
1659  -- by definition (ie. referring to objects in
1660  -- other carousels is only done via
1661  -- LiteOptionsProfile). If wrong, it is
1662  -- probably a broadcast error and can/should
1663  -- be ignored.
1664  */
1665  L2_DATA_CHK(
1666  pLoadRequest->objectLocation.carouselId == pCurrOC->root.rcid,
1667  dsmDP1(("DATA ERROR: objectLocation carouselId (%u) does not match current ID (%u)\n",
1668  pLoadRequest->objectLocation.carouselId, pCurrOC->root.rcid)),
1669  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1670  progressLoad = FALSE
1671  );
1672  }
1673  else
1674  {
1675  dsmDP1(("DATA ERROR: Invalid binding\n"));
1676  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1677  }
1678  }
1679  else
1680  {
1681  dsmDP2(("INFO: Binding not found: %s\n",
1682  nextPathElement));
1683  pLoadRequest->rlr.status = LRS_ABORTED_PATH_ERROR;
1684  }
1685 
1686  MEMPTR_CLOSE( mpBindingData );
1687  }
1688  else
1689  {
1690  /* -- This is a target directory object so load is
1691  -- completed */
1692 
1693  switch (pLoadRequest->rlr.targetKind)
1694  {
1695  case TT_PREFETCH_DIR_OBJ: /* internal pre-fetch of directory */
1696  pLoadRequest->rlr.status = LRS_LOADED;
1697  break;
1698 
1699  case TT_TMP_OBJECT:
1700  case TT_GEN_OBJECT:
1701  dsmAssert((objInf.objectKind == SRG_STR ||
1702  objInf.objectKind == DIR_STR));
1703  /* -- This is client load of SRG or DIR object */
1704  pLoadRequest->rlr.status = LRS_LOADED;
1705  break;
1706 
1707  default:
1708  dsmDP1(("ERROR: Load request - invalid"));
1709  dsmDP1((" directory target kind: %u\n",
1710  pLoadRequest->rlr.targetKind));
1711  dsmAssert((0));
1712 
1713  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1714  err = CLDSM_ERR_INTERNAL;
1715  break;
1716  }
1717  }
1718  }
1719  else
1720  {
1721  /* -- This is a 'leaf' object so load is completed */
1722 
1723  dsmAssert((objInf.objectKind == FIL_STR ||
1724  objInf.objectKind == STR_STR ||
1725  objInf.objectKind == STE_STR));
1726 
1727  pLoadRequest->rlr.status = LRS_LOADED;
1728  }
1729  }
1730 
1731 
1732  /* -- If load is completed, extract/store the object info */
1733 
1734  if (pLoadRequest->rlr.status == LRS_LOADED)
1735  {
1736  MEMPTR_GET_DIFF( mpModuleData, mpObjectData, objOffset );
1737  dsmAssert((objOffset >= 0));
1738 
1739  pLoadRequest->targetObjectOffset = (U32BIT) objOffset;
1740  pLoadRequest->targetObjectInfo = objInf;
1741  }
1742 
1743 
1744  /*
1745  -- If the current module has been (successfully) used to advance
1746  -- or complete a client request (and it is not 'loaded' - ie. in
1747  -- use by a client) then promote it in the module priority list
1748  */
1749  if ((pLoadRequest->rlr.status == LRS_LOADED) || (progressLoad))
1750  {
1751  if (DSC_LoadRsqtPriority(&pLoadRequest->rlr) != SF_PRIORITY_LOW)
1752  {
1753  if (pCurrModule->loadedCount == 0)
1754  {
1755  /* -- Promote current module to head of priority list */
1756  LLInsertHead( idp->llcModulePriority, pCurrModule );
1757  }
1758  /* else - module is loaded */
1759  }
1760  /* else - this is not a client request */
1761  }
1762  /* else - load is not completed or progressing */
1763  }
1764  /* else - don't process current object */
1765 
1766  MEMPTR_CLOSE( mpObjectData );
1767  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pCurrModule->hModuleData, mpModuleData );
1768 
1769 
1770  if (progressLoad)
1771  {
1772  /*
1773  -- Load is not finished (ie. completed or aborted). Determine if
1774  -- module containing 'next' object is in cache so we can progress
1775  -- the load request further.
1776  */
1777 
1778  /* -- Initial state */
1779  progressLoad = FALSE;
1780 
1781  /* -- Is the next module the same as the current? */
1782  if (pLoadRequest->objectLocation.moduleId ==
1783  pCurrModule->moduleInfo.moduleId)
1784  {
1785  /* -- Load request can be progressed further */
1786  progressLoad = TRUE;
1787  }
1788  else
1789  {
1790  /* -- Next module is not the same as current module */
1791 
1792  /* -- Current module no longer required */
1793  pLoadRequest->pModule = NULL;
1794 
1795  /* -- Is the next DC (not) the same as the current DC? */
1796  if ((pLoadRequest->tap.transactionId &
1797  TRANSACTION_ID_IDENT_MASK) !=
1798  pCurrDC->dataCarouselId)
1799  {
1800  /* -- Current DC no longer required */
1801  /* -- Search DC list to see if next one is available */
1802  pLoadRequest->pDataCarousel =
1803  DSC_DataCrslListFindById( pCurrOC->root.llcDataCarousels,
1804  pLoadRequest->tap.transactionId );
1805  }
1806  /* else - next DC is the same as current */
1807 
1808  /* -- Is the next DC available */
1809  if (pLoadRequest->pDataCarousel != NULL)
1810  {
1811  /* -- Next DC is available */
1812  pNextDC = pLoadRequest->pDataCarousel;
1813 
1814  /* -- Find if next module is available */
1815  pLoadRequest->pModule =
1816  DSC_ModuleListFindById( pNextDC->llcDcModules,
1817  pLoadRequest->objectLocation.moduleId );
1818 
1819  if (pLoadRequest->pModule != NULL)
1820  {
1821  /* -- Next module is available */
1822  pNextModule = pLoadRequest->pModule;
1823 
1824  /* -- Is next module cached? */
1825  if (pNextModule->status == MS_CACHED)
1826  {
1827  /* -- Load request can be progressed further */
1828  progressLoad = TRUE;
1829  }
1830  /* else - next module is not cached so load cannot be
1831  progressed */
1832  }
1833  /* else - next module is not available so load cannot be
1834  progressed */
1835  }
1836  /* else - next DC is not available so load cannot be
1837  progressed */
1838  }
1839 
1840  if (!progressLoad)
1841  {
1842  /* -- This load request is stalled */
1843  pLoadRequest->rlr.status = LRS_STALLED_MODULE;
1844  }
1845  }
1846  }
1847  while (progressLoad);
1848 
1849  DEBUG_CHK( err == CLDSM_OK,
1850  dsmDP1(("ERROR: ProgressLoadRequest: %u\n", err)));
1851  dsmDP3(("exit ProgressLoadRequest -> rtn: %u\n", err));
1852  return err;
1853 }
1854 
1855 /* /////////////////////////////////////////////////////////////////////////////
1856 // UpdateModuleLoadRequests
1857 //
1859 static E_DscError UpdateModuleLoadRequests( P_DsmCoreInst idp, P_Module pCurrModule )
1860 {
1861  P_LoadRequest pLoadRequest;
1862  E_DscError newErr = CLDSM_OK;
1863  E_DscError err = CLDSM_OK;
1864  BOOLEAN currModuleContainsTargetObject = FALSE;
1865  BOOLEAN finaliseLoad = FALSE;
1866 
1867  dsmDP3(("UpdateModuleLoadRequests()\n"));
1868  dsmAssert((idp != NULL));
1869  dsmAssert((pCurrModule != NULL));
1870 
1871  /* -- Current module must be cached */
1872  dsmAssert((pCurrModule->status == MS_CACHED));
1873 
1874  /* -- Current module must be decompressed */
1875  dsmAssert((pCurrModule->hModuleData != NULL));
1876 
1877  /* -- Current module must have load request list */
1878  dsmAssert((pCurrModule->llcLoadRequests != NULL));
1879 
1880  /* -- Update any/each loadRequest waiting on this module (oldest first) */
1881  /* -- There should always be at-least one loadRequest in the list */
1882  pLoadRequest = LLTail( pCurrModule->llcLoadRequests );
1883  while (pLoadRequest != NULL)
1884  {
1885  dsmAssert((LLParent(pLoadRequest, MODULE_LOAD_REQUEST_LIST) == pCurrModule));
1886  DSC_ModuleRemoveLoadRequest(idp, pLoadRequest);
1887 
1888  /* -- These must be the same */
1889  dsmAssert((pLoadRequest->pModule == pCurrModule));
1890 
1891  DSC_ModuleUse( idp, pCurrModule );
1892 
1893  /* -- Load request must be in one of these states */
1894  dsmAssert(((pLoadRequest->rlr.status == LRS_STALLED_MODULE) ||
1895  (pLoadRequest->rlr.status == LRS_STALLED_SRG_MODULE)));
1896 
1897  /*
1898  -- NB. Current module is always decompressed so we do not have to
1899  -- handle condition where this module is re-acquired or unloaded
1900  -- in ProgressLoadRequest (due to decompress failure).
1901  */
1902  err = ProgressLoadRequest( idp, pLoadRequest );
1903  if (!err)
1904  {
1905  finaliseLoad = FALSE;
1906 
1907  switch (pLoadRequest->rlr.status)
1908  {
1909  case LRS_LOADED:
1910  if ((pLoadRequest->rlr.targetKind == TT_GEN_OBJECT) &&
1911  (pLoadRequest->rlr.target != NULL))
1912  {
1913  /* -- This is a client object load so handle the
1914  -- caching rules */
1915  dsmAssert((pLoadRequest->pModule != NULL));
1916  dsmAssert((pLoadRequest->pModule->status == MS_CACHED));
1917  dsmAssert((pLoadRequest->pModule->hModuleData != NULL));
1918  if (pCurrModule == pLoadRequest->pModule)
1919  {
1920  /*
1921  -- The current (just cached) module contains the
1922  -- target object so complete the load and
1923  -- update the module cache status when all load
1924  -- requests have been processed (see below current
1925  -- loop)
1926  */
1927  currModuleContainsTargetObject = TRUE;
1928  finaliseLoad = TRUE;
1929  }
1930  else
1931  {
1932  /*
1933  -- The current module only supplied a missing part
1934  -- of the path to the target object which is actually
1935  -- contained in another module that was already
1936  -- in the cache . In this case, update this (target)
1937  -- module's cache status before finalising the load
1938  -- (may delete/destroy this (target) module).
1939  */
1940  /* -- Update cache status of module according to
1941  -- module's current caching rules. Don't flush
1942  -- parent DC since we will immediately reload
1943  -- module if it is destroyed. */
1944  UpdateModuleCachingNoFlush( idp, pLoadRequest );
1945 
1946  if (pLoadRequest->pModule == NULL)
1947  {
1948  newErr = LoadStalledModule( idp, pLoadRequest );
1949  if (newErr)
1950  {
1951  err = handleInLoopError( idp, err, newErr );
1952 
1953  /* -- Abort load request */
1954  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1955  finaliseLoad = TRUE;
1956  }
1957  }
1958  else
1959  {
1960  /* -- Object's module is still cached so load
1961  -- is complete */
1962  finaliseLoad = TRUE;
1963  }
1964  }
1965  }
1966  else
1967  {
1968  /* -- This is either a client/internal pre-fetch or it
1969  -- is not an object load (eg. a carousel load) - so
1970  -- load is complete */
1971  finaliseLoad = TRUE;
1972  }
1973  break;
1974 
1975 
1976  case LRS_ABORTED_PATH_ERROR:
1977  case LRS_ABORTED_LOAD_ERROR:
1978  finaliseLoad = TRUE;
1979  break;
1980 
1981 
1982  case LRS_STALLED_MODULE:
1983  case LRS_STALLED_SRG_MODULE:
1984 
1985  newErr = LoadStalledModule( idp, pLoadRequest );
1986 
1987  if (newErr)
1988  {
1989  err = handleInLoopError( idp, err, newErr );
1990 
1991  /* -- Abort load request & notify client */
1992  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
1993  finaliseLoad = TRUE;
1994  }
1995  break;
1996 
1997  /*
1998  *** PLACEHOLDER - NOT CURRENTLY VALID ***
1999  case LRS_STALLED_DSI:
2000  TODO: Allow object loads before DSI acquired
2001  break;
2002  */
2003 
2004  default:
2005  /* -- Illegal status */
2006  dsmDP1(("ERROR: Illegal loadRequest status = %u\n",
2007  pLoadRequest->rlr.status));
2008  dsmAssert((0));
2009 
2010  err = handleInLoopError( idp, err, CLDSM_ERR_INTERNAL );
2011  finaliseLoad = TRUE;
2012  break;
2013  }
2014  }
2015  else
2016  {
2017  err = handleInLoopError( idp, err, CLDSM_ERR_INTERNAL );
2018 
2019  /* -- Abort load request & notify client */
2020  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
2021  finaliseLoad = TRUE;
2022  }
2023 
2024  DSC_ModuleUnUse( idp, pCurrModule );
2025 
2026  if (finaliseLoad)
2027  {
2028  /* -- NB. hOC must be closed when making this call
2029  -- since it may get unloaded from notify callback */
2030  DSC_LoadRsqtFinalise( idp, (P_RootLoadRqst)pLoadRequest );
2031  }
2032  pLoadRequest = (pCurrModule->llcLoadRequests) ? LLTail( pCurrModule->llcLoadRequests ) : NULL;
2033  }
2034 
2035  if (currModuleContainsTargetObject &&
2036  pCurrModule->cachingRules == CACHE_RULES_FROM_STREAM)
2037  {
2038  /* -- The current module contains the target of at least one
2039  -- object load so update cache status of module according to
2040  -- its current caching rules (may delete/destroy module) */
2041  /* -- Module must be cached with valid moduleData */
2042  dsmAssert((pCurrModule->status == MS_CACHED));
2043  dsmAssert((pCurrModule->hModuleData != NULL));
2044 
2045  /* -- Module must not have an active section filter */
2046  dsmAssert((pCurrModule->pDdbSf == NULL));
2047 
2048  /* -- Must not be any outstanding load requests on module */
2049  dsmAssert((pCurrModule->llcLoadRequests == NULL));
2050 
2051  /* -- NB. Without outstanding Load Requests, the data on
2052  -- this module can be refreshed now */
2053  DSC_ModuleDataRefresh( idp, pCurrModule );
2054  }
2055 
2056  DEBUG_CHK( err == CLDSM_OK,
2057  dsmDP1(("ERROR: UpdateModuleLoadRequests: %u\n", err)));
2058  dsmDP3(("exit UpdateModuleLoadRequests -> rtn: %u\n", err));
2059  return err;
2060 }
2061 
2062 /*
2063 -- Internally prefetch a directory object
2064 --
2065 -- NB. This can be called re-entrantly (max depth = MAX_DIRECTORY_DEPTH).
2066 -- NB. This does nothing if the cache is full
2067 --
2068 */
2069 static E_DscError PreFetchRelativeDirObj( P_DsmCoreInst idp,
2070  P_LoadRequest pCurrLR, P_ObjectLocation pLocation,
2071  P_DeliveryParaTap pTap, U32BIT timeout )
2072 {
2073  P_ObjectCarousel pOC;
2074  P_LoadRequest pLoadRequest;
2075  E_DscError err = CLDSM_OK;
2076  BOOLEAN loadFinished = FALSE;
2077 
2078  dsmDP3(("PreFetchRelativeDirObj()\n"));
2079  dsmAssert((idp != NULL));
2080  dsmAssert((pCurrLR != NULL));
2081 
2082  /* -- Increment recursion depth counter */
2083  idp->pfrdoCallDepth++;
2084 
2085  /* -- Detect possible 'infinite loops' caused by erroneous circular
2086  -- references in directory hierarchy */
2087  if (idp->pfrdoCallDepth > MAX_DIRECTORY_DEPTH)
2088  {
2089  dsmDP1(("ERROR: PreFetchRelativeDirObj recursion limit reached: %u\n", idp->pfrdoCallDepth));
2090  err = CLDSM_ERR_RECURSION_LIMIT_REACHED;
2091  dsmAssert((0));
2092  }
2093  else if (idp->cacheFull == FALSE)
2094  {
2095  pOC = pCurrLR->pObjCarousel;
2096 
2097  /* -- Mark current module used since this function allocates cache
2098  -- memory and we don't want the module to be deleted! */
2099  DSC_ModuleUse( idp, pCurrLR->pModule );
2100 
2101  dsmAssert((pOC->root.status == RCS_LOADED));
2102 
2103  err = DSC_LoadRsqtCreate( idp, sizeof(S_LoadRequest), TT_PREFETCH_DIR_OBJ, NULL,
2104  (F_LoadFinalise)PreFetchDirLoadFinalise, (P_RootLoadRqst *)&pLoadRequest );
2105  if (!err)
2106  {
2107  pLoadRequest->pObjCarousel = pOC;
2108 
2109  pLoadRequest->pDataCarousel = pCurrLR->pDataCarousel;
2110  pLoadRequest->pModule = pCurrLR->pModule;
2111  pLoadRequest->objectLocation = *pLocation;
2112  pLoadRequest->tap = *pTap;
2113 
2114  err = ProgressLoadRequest( idp, pLoadRequest );
2115  if (!err)
2116  {
2117  switch (pLoadRequest->rlr.status)
2118  {
2119  case LRS_LOADED:
2120  /* -- NB. Possible re-entrant call */
2121  PreFetchDirLoadFinalise( idp, pLoadRequest );
2122  loadFinished = TRUE;
2123  break;
2124 
2125  case LRS_STALLED_MODULE:
2126  err = LoadStalledModule( idp, pLoadRequest );
2127  break;
2128 
2129  case LRS_ABORTED_LOAD_ERROR:
2130  loadFinished = TRUE;
2131  break;
2132 
2133  default:
2134  err = CLDSM_ERR_INTERNAL;
2135  break;
2136  }
2137  }
2138  if (err || loadFinished)
2139  {
2140  /* -- Error so destroy/free any allocated memory objects */
2141  DSC_LoadRsqtDestroy( idp, (P_RootLoadRqst)pLoadRequest );
2142  }
2143  }
2144 
2145  /* -- Finished using current module */
2146  DSC_ModuleUnUse( idp, pCurrLR->pModule );
2147  }
2148 
2149  /* -- Decrement recursion depth counter */
2150  idp->pfrdoCallDepth--;
2151 
2152  DEBUG_CHK( err == CLDSM_OK,
2153  dsmDP1(("ERROR: PreFetchRelativeDirObj: %u\n", err)));
2154  dsmDP3(("exit PreFetchRelativeDirObj -> rtn: %u\n", err));
2155  return err;
2156 }
2157 
2158 /*
2159 -- Internally prefetch a non-directory object
2160 --
2161 -- NB. This does nothing if the cache is full
2162 --
2163 */
2164 static E_DscError PreFetchRelativeNonDirObj( P_DsmCoreInst idp,
2165  P_LoadRequest pCurrLR, P_ObjectLocation pLocation,
2166  P_DeliveryParaTap pTap, U32BIT timeout )
2167 {
2168  P_ObjectCarousel pOC;
2169  P_LoadRequest pLoadRequest;
2170  E_DscError err = CLDSM_OK;
2171  BOOLEAN loadFinished = FALSE;
2172 
2173  dsmDP3(("PreFetchRelativeNonDirObj()\n"));
2174  dsmAssert((idp != NULL));
2175  dsmAssert((pCurrLR != NULL));
2176 
2177  if (idp->cacheFull == FALSE)
2178  {
2179  pOC = pCurrLR->pObjCarousel;
2180 
2181  /* -- Mark current module used since this function allocates cache
2182  -- memory and we don't want the module to be deleted! */
2183  DSC_ModuleUse( idp, pCurrLR->pModule );
2184 
2185  dsmAssert((pOC->root.status == RCS_LOADED));
2186 
2187  err = DSC_LoadRsqtCreate( idp, sizeof(S_LoadRequest), TT_PREFETCH_NON_DIR_OBJ, pOC,
2188  NULL, (P_RootLoadRqst *)&pLoadRequest );
2189  if (!err)
2190  {
2191  pLoadRequest->pObjCarousel = pOC;
2192 
2193  pLoadRequest->pDataCarousel = pCurrLR->pDataCarousel;
2194  pLoadRequest->pModule = pCurrLR->pModule;
2195  pLoadRequest->objectLocation = *pLocation;
2196  pLoadRequest->tap = *pTap;
2197 
2198  err = ProgressLoadRequest( idp, pLoadRequest );
2199  if (!err)
2200  {
2201  switch (pLoadRequest->rlr.status)
2202  {
2203  case LRS_LOADED:
2204  loadFinished = TRUE;
2205  break;
2206 
2207  case LRS_STALLED_MODULE:
2208  err = LoadStalledModule( idp, pLoadRequest );
2209  break;
2210 
2211  case LRS_ABORTED_LOAD_ERROR:
2212  loadFinished = TRUE;
2213  break;
2214 
2215  default:
2216  err = CLDSM_ERR_INTERNAL;
2217  break;
2218  }
2219  }
2220  if (err || loadFinished)
2221  {
2222  /* -- Error so destroy/free any allocated memory objects */
2223  DSC_LoadRsqtDestroy( idp, (P_RootLoadRqst)pLoadRequest );
2224  }
2225  }
2226  /* -- Finished using current module */
2227  DSC_ModuleUnUse( idp, pCurrLR->pModule );
2228  }
2229  DEBUG_CHK( err == CLDSM_OK,
2230  dsmDP1(("ERROR: PreFetchRelativeNonDirObj: %u\n", err)));
2231  dsmDP3(("exit PreFetchRelativeNonDirObj -> rtn: %u\n", err));
2232  return err;
2233 }
2234 
2235 /*
2236 -- Parse all DIR bindings and pre-fetch any sub-dirs.
2237 --
2238 -- For all non-dir bindings also pre-fetch any objs that are found in
2239 -- new (ie. as yet, not cached) data carousels/DIIs.
2240 --
2241 -- Stop parsing bindings if any error encountered.
2242 --
2243 -- NB. This can be called re-entrantly
2244 --
2245 */
2246 static E_DscError PreFetchNewDirsAndDIIsFromLoadedDir( P_DsmCoreInst idp,
2247  P_LoadRequest pLoadRequest )
2248 {
2249  P_Module pModule = NULL;
2250  U32BIT bindingKind;
2251  U16BIT numBindings;
2252  MemPtr mpObjectData;
2253  MemPtr mpBindingData;
2254  E_DscError err = CLDSM_OK;
2255  P_DataCarousel pDC = NULL;
2256  P_ObjectCarousel pOC;
2257  S_ObjectLocation objLocation;
2258  S_DeliveryParaTap objTap;
2259 
2260  dsmDP3(("PreFetchNewDirsAndDIIsFromLoadedDir()\n"));
2261  dsmAssert((idp != NULL));
2262  dsmAssert((pLoadRequest != NULL));
2263 
2264 
2265  /* -- Increment recursion depth counter */
2266  idp->pfsdndCallDepth++;
2267 
2268  /* -- Detect possible 'infinite loops' caused by erroneous circular
2269  -- references in directory hierarchy */
2270  if (idp->pfsdndCallDepth > MAX_DIRECTORY_DEPTH)
2271  {
2272  dsmDP1(("ERROR: PreFetchNewDirsAndDIIsFromLoadedDir recursion limit reached: %u\n",
2273  idp->pfrdoCallDepth));
2274  err = CLDSM_ERR_RECURSION_LIMIT_REACHED;
2275  dsmAssert((0));
2276  goto _return;
2277  }
2278 
2279  pModule = pLoadRequest->pModule;
2280 
2281  /* -- Module should be cached and already decompressed (when
2282  -- SRG object info was extracted */
2283  dsmAssert((pModule->status == MS_CACHED));
2284  dsmAssert((pModule->hModuleData != NULL));
2285 
2286  MEMPTR_SEQ_OPEN( MEM_CONTEXT,
2287  moduleDataPtr(pModule->hModuleData), pLoadRequest->targetObjectOffset,
2288  pLoadRequest->targetObjectInfo.objectLen,
2289  /*threadsafe*/ FALSE, mpObjectData );
2290 
2291  MEMPTR_OPEN( mpObjectData, mpBindingData );
2292 
2293  numBindings = odDirCountAndFirstBinding( mpObjectData, &(pLoadRequest->targetObjectInfo), &mpBindingData );
2294 
2295  while (numBindings--)
2296  {
2297  if (odDirGetBindingKind( mpBindingData, &bindingKind ))
2298  {
2299  if (bindingKind == DIR_STR)
2300  {
2301  /* -- Directory binding so pre-fetch it */
2302  if (odDirGetBindingInfo( mpBindingData, &objLocation, &objTap ))
2303  {
2304  err = PreFetchRelativeDirObj( idp, pLoadRequest, &objLocation, &objTap,
2305  /*timeout*/ 0 );
2306 
2307  if (err)
2308  {
2309  break;
2310  }
2311  }
2312  }
2313  else
2314  {
2315  /* -- Non-directory binding */
2316  /* -- If binding location DII does not already exist
2317  -- pre-fetch binding object*/
2318 
2319  /*
2320  -- TODO: Improve efficiency since current
2321  -- implementation is VERY processor intensive.
2322  --
2323  -- NB. This is due to calling DSC_DataCrslListFindById (which
2324  -- is itself very inefficient/processor intensive)
2325  -- and getting all binding info on every (non-dir) binding
2326  -- (when only need transactionId on most of them).
2327  */
2328  if (odDirGetBindingInfo( mpBindingData, &objLocation, &objTap ))
2329  {
2330  if (objLocation.uiBindingTag == TAG_LITE_OPTIONS)
2331  {
2332  U16BIT service_id = 0;
2333  U32BIT carousel_id = 0;
2334 
2335  H_DsmCarousel carouselHandle;
2336  U32BIT temp32 = 0;
2337  U16BIT temp16 = 0;
2338  P_ObjectCarousel pNewOC;
2339 
2340  carousel_id = (U32BIT)objLocation.dvbCarouselNSAPaddress[2];
2341  carousel_id <<= 24;
2342  carousel_id &= 0xFF000000;
2343  temp32 = (U32BIT)objLocation.dvbCarouselNSAPaddress[3];
2344  carousel_id |= ((temp32 << 16) & 0x00FF0000);
2345  temp32 = (U32BIT)objLocation.dvbCarouselNSAPaddress[4];
2346  carousel_id |= ((temp32 << 8) & 0x0000FF00);
2347  temp32 = (U32BIT)objLocation.dvbCarouselNSAPaddress[5];
2348  carousel_id |= (temp32 & 0x000000FF);
2349 
2350  service_id = objLocation.dvbCarouselNSAPaddress[14];
2351  service_id <<= 8;
2352  service_id &= 0xFF00;
2353  temp16 = objLocation.dvbCarouselNSAPaddress[15];
2354  service_id |= (temp16 & 0x00FF);
2355 
2356  dsmDP2(("CALL CDSM_LoadCarousel(carID:%u)\n", carousel_id));
2357 
2358  err = CDSM_LoadCarousel(idp, service_id, carousel_id,
2359  SIQUERY_CAROUSEL, &carouselHandle);
2360 
2361  /* Abort */
2362  if (err != CLDSM_OK)
2363  {
2364  break;
2365  }
2366 
2367  pNewOC = (P_ObjectCarousel)carouselHandle;
2368 
2369  pNewOC->bOCLiteOptionsObjectProcessing = TRUE;
2370  }
2371  else
2372  {
2373  pOC = pLoadRequest->pObjCarousel;
2374  dsmAssert((pOC != NULL));
2375 
2376  pDC = DSC_DataCrslListFindById( pOC->root.llcDataCarousels, objTap.transactionId );
2377 
2378  if (pDC == NULL)
2379  {
2380  err = PreFetchRelativeNonDirObj( idp, pLoadRequest, &objLocation, &objTap, /*timeout*/ 0 );
2381  if (err)
2382  {
2383  break;
2384  }
2385  }
2386  }
2387  }
2388  }
2389  }
2390 
2391  if (!odDirGetNextBinding( mpBindingData, &mpBindingData ))
2392  {
2393  break;
2394  }
2395  }
2396 
2397  MEMPTR_CLOSE( mpBindingData );
2398  MEMPTR_SEQ_CLOSE( MEM_CONTEXT, pModule->hModuleData, mpObjectData );
2399 
2400 
2401 _return:
2402  /* -- Decrement recursion depth counter */
2403  idp->pfsdndCallDepth--;
2404 
2405  DEBUG_CHK( err == CLDSM_OK,
2406  dsmDP1(("ERROR: PreFetchNewDirsAndDIIsFromLoadedDir: %u\n", err)));
2407  dsmDP3(("exit PreFetchNewDirsAndDIIsFromLoadedDir -> rtn: %u\n", err));
2408 
2409  return err;
2410 }
2411 
2412 /* /////////////////////////////////////////////////////////////////////////////
2413 // UpdateModuleCachingNoFlush
2414 //
2415 // Special version that does not flush the parent data carousel (ie. even if
2416 // it is now empty).
2417 // NB. Only used for special cases of cache priority 0 (fromStream) handling.
2418 //
2420 static void UpdateModuleCachingNoFlush( P_DsmCoreInst idp, P_LoadRequest pLoadRequest )
2421 {
2422  P_Module pModule;
2423  P_ObjectCarousel pOC;
2424  P_DataCarousel pDC;
2425 
2426  dsmAssert((idp != NULL));
2427  dsmAssert((pLoadRequest != NULL));
2428 
2429  pModule = pLoadRequest->pModule;
2430  dsmAssert((pModule != NULL));
2431 
2432  /* -- Module must be cached with valid moduleData */
2433  dsmAssert((pModule->status == MS_CACHED));
2434  dsmAssert((pModule->hModuleData != NULL));
2435 
2436  /* -- Module must not have an active section filter */
2437  dsmAssert((pModule->pDdbSf == NULL));
2438 
2439  /* -- Must not be any outstanding load requests on module */
2440  dsmAssert((pModule->llcLoadRequests == NULL));
2441 
2442  if (pModule->cachingRules == CACHE_RULES_FROM_STREAM)
2443  {
2444  /* -- Find parent DC and OC for module */
2445  pDC = LLParent( pModule, DC_MODULE_LIST );
2446  pOC = LLParent( pDC, OC_DATA_CAROUSEL_LIST );
2447  /* -- NB. Destroy's module or moves it to delete list
2448  -- depending on whether it has any objects loaded */
2449  dsmAssert((pOC != NULL));
2450  dsmAssert((pDC != NULL));
2451 
2452  if (DSC_ModuleDataRefresh( idp, pModule ) == CLDSM_OK)
2453  {
2454  /* Caching rules have caused the object's module to be destroyed/deleted, so
2455  * reset the state of the load to be stalled on the now 'missing' final module. */
2456  if (DSC_ObjCrslSrgModule(pOC) == pModule)
2457  {
2458  /* -- SRG module was destroyed */
2459  pLoadRequest->rlr.status = LRS_STALLED_SRG_MODULE;
2460  }
2461  else
2462  {
2463  /* -- non-SRG module was destroyed */
2464  pLoadRequest->rlr.status = LRS_STALLED_MODULE;
2465  }
2466  }
2467  }
2468  dsmDP3(("exit UpdateModuleCachingNoFlush\n"));
2469 }
2470 
2471 static void ProcessLiteOptionsObjects( P_DsmCoreInst idp,
2472  P_ObjectCarousel pCarousel )
2473 {
2474  pLiteOptionObject_t pLiteObjFromListToDelete = NULL;
2475  pLiteOptionObject_t pLiteObjFromList = NULL;
2476  ListId_t listId;
2477 
2478  /* Get listId and first OC in list from Control block */
2479  listId = LListId( pCarousel->llcOcPostponedLiteObjectLoads );
2480  pLiteObjFromList = LLHead( pCarousel->llcOcPostponedLiteObjectLoads );
2481  dsmDP2(("LITE list %u => handle = %#p\n", listId, pLiteObjFromList));
2482 
2483  while (pLiteObjFromList)
2484  {
2485  pLiteObjFromListToDelete = NULL;
2486 
2487  dsmDP2(("CALL liteOptionsObjectHandle: name = %s hRequest = %#p\n",
2488  pLiteObjFromList->name, pLiteObjFromList->pLoadRequest));
2489 
2490  lmLiteOptionsObjectHandle(idp, pLiteObjFromList->name, pLiteObjFromList->pLoadRequest);
2491 
2492  if (LRS_LITE_OPTIONS_LOADED == pLiteObjFromList->pLoadRequest->rlr.status)
2493  {
2494  dsmDP2(("LITE_OPTIONS: Finalise object loading\n"));
2495  ObjectLoadFinalise(idp, pLiteObjFromList->pLoadRequest);
2496 
2497  pLiteObjFromListToDelete = pLiteObjFromList;
2498  }
2499 
2500 
2501  /* remove current from list */
2502  if (NULL != pLiteObjFromListToDelete)
2503  {
2504  LLRemove( pLiteObjFromListToDelete, OC_LITE_OBJECT_LOAD_LIST );
2505  }
2506  pLiteObjFromList = LLNext( pLiteObjFromList, listId );
2507  }
2508 }
2509 
2510 static void ProcessLoadRequestsOnCarousel( P_DsmCoreInst idp, P_ObjectCarousel pOC )
2511 {
2512  P_LoadRequest pNextRequest;
2513  P_LoadRequest pLoadRequest;
2514  ListId_t listId;
2515 
2516  listId = LListId( idp->llcCurrLoadRequests );
2517  pLoadRequest = LLHead( idp->llcCurrLoadRequests );
2518 
2519  do
2520  {
2521  pNextRequest = LLNext( pLoadRequest, listId );
2522  if (pLoadRequest->rlr.targetKind & TT_GEN_OBJECT)
2523  {
2524  if (pLoadRequest->rlr.status != LRS_ABORT_PENDING_RELOAD)
2525  {
2526  //lmStopModuleLoadRequest( idp, &pLoadRequest );
2527  if (pLoadRequest->rlr.status == LRS_STALLED_MODULE || pLoadRequest->rlr.status == LRS_STALLED_SRG_MODULE)
2528  {
2529  dsmAssert((LLParent(pLoadRequest, MODULE_LOAD_REQUEST_LIST) == pLoadRequest->pModule));
2530  DSC_ModuleRemoveLoadRequest(idp, pLoadRequest);
2531  }
2532  }
2533  else
2534  {
2535  pLoadRequest->pDataCarousel = NULL;
2536  pLoadRequest->pModule = NULL;
2537  if (pLoadRequest->rlr.target)
2538  {
2539  P_DsmObject pDsmObject = (P_DsmObject)pLoadRequest->rlr.target;
2540  pDsmObject->pObjCarousel = pOC;
2541  pOC->loadedObjectCount++;
2542  }
2543  }
2544  pLoadRequest->pObjCarousel = pOC;
2545  pLoadRequest->rlr.status = LRS_INITIAL;
2546  pLoadRequest->objectLocation = pOC->srgObjLoc;
2547  pLoadRequest->tap = pOC->srgTap;
2548  pLoadRequest->remainingPathOffset = 0;
2549  if (LoadRequestOnSrg( idp, pOC, pLoadRequest ) == CLDSM_OK &&
2550  pLoadRequest->rlr.status == LRS_STALLED_MODULE)
2551  {
2552  if (LoadStalledModule( idp, pLoadRequest ) == CLDSM_OK)
2553  {
2554  }
2555  else
2556  {
2557  pLoadRequest->rlr.status = LRS_ABORTED_LOAD_ERROR;
2558  DSC_LoadRsqtFinalise( idp, (P_RootLoadRqst)pLoadRequest );
2559  }
2560  }
2561  else
2562  {
2563  dsmAssert((pLoadRequest->rlr.status != LRS_STALLED_SRG_MODULE));
2564  DSC_LoadRsqtFinalise( idp, (P_RootLoadRqst)pLoadRequest );
2565  }
2566  }
2567  pLoadRequest = pNextRequest;
2568  }
2569  while (pLoadRequest);
2570 }
2571 
2572 /* -- LOAD FINALISE FUNCTIONS */
2573 
2574 void lmCarouselLoadFinalise( P_DsmCoreInst idp,
2575  P_LoadRequest pLoadRequest )
2576 {
2577  P_ObjectCarousel pCarousel;
2578  E_OCLoadStatus status = OC_LOAD_ABORTED_ERROR;
2579  E_DscError err = CLDSM_OK;
2580 
2581  dsmDP3(("carouselLoadFinalise()\n"));
2582  dsmAssert((idp != NULL));
2583  dsmAssert((pLoadRequest != NULL));
2584  dsmAssert((pLoadRequest->rlr.targetKind == TT_CAROUSEL));
2585 
2586  pCarousel = pLoadRequest->pObjCarousel;
2587 
2588  dsmDP2(("carouselLoadFinalise() pCarousel->carouselId = %u\n", pCarousel->root.rcid));
2589 
2590  dsmDP2(("carouselLoadFinalise() status = %u\n", pLoadRequest->rlr.status));
2591 
2592  switch (pLoadRequest->rlr.status)
2593  {
2594  case LRS_STALLED_SRG_MODULE:
2595  dsmAssert((pCarousel->root.status == RCS_BOOTED));
2596  status = OC_LOAD_BOOTED;
2597  break;
2598 
2599  case LRS_LOADED:
2600  pCarousel->root.status = RCS_LOADED;
2601  status = OC_LOAD_COMPLETED;
2602 
2603  DSC_ObjCrslUpdateSuiLoaded(idp,pCarousel);
2604 
2605  if (!pCarousel->bOCLiteOptionsObjectProcessing &&
2606  idp->setup.turboCaching == TRUE)
2607  {
2608  /* -- Initiate hierarchical cache pre-fill */
2609  err = PreFetchNewDirsAndDIIsFromLoadedDir( idp, pLoadRequest );
2610 
2611  if (err)
2612  {
2613  dsmDP1(("ERROR: carouselLoadFinalise: %u\n", err));
2614  /* -- TODO: Provide error returns from finalise funcs? */
2615  /* -- No error return from this function
2616  -- (currently) so handle as a loop error */
2617  err = handleInLoopError( idp, CLDSM_OK, err );
2618  }
2619  }
2620  break;
2621 
2622  case LRS_ABORTED_TIMEOUT:
2623  pCarousel->root.status = RCS_LOAD_FAILED;
2624  status = OC_LOAD_ABORTED_TIMEOUT;
2625  break;
2626 
2627  case LRS_ABORTED_PATH_ERROR:
2628  pCarousel->root.status = RCS_LOAD_FAILED;
2629  status = OC_LOAD_ABORTED_PATH_ERROR;
2630  break;
2631 
2632  case LRS_ABORTED_LOAD_ERROR:
2633  pCarousel->root.status = RCS_LOAD_FAILED;
2634  status = OC_LOAD_ABORTED_ERROR;
2635  break;
2636 
2637  case LRS_ABORTED_BY_REQUESTER:
2638  pCarousel->root.status = RCS_LOAD_FAILED;
2639  status = OC_LOAD_ABORTED_UNLOAD;
2640  break;
2641 
2642  default: /*** INTERNAL ERROR ***/
2643  dsmAssert((0));
2644  pCarousel->root.status = RCS_LOAD_FAILED;
2645  status = OC_LOAD_ABORTED_ERROR;
2646  break;
2647  }
2648  if (pCarousel->root.status != RCS_BOOTED)
2649  {
2650  /* -- Load request is completed so NULL ref */
2651  pCarousel->root.pLoadRqst = NULL;
2652  }
2653 
2654  if (idp->setup.notifyCarouselLoadEventFunc)
2655  {
2656  idp->setup.notifyCarouselLoadEventFunc((H_DsmCarousel)pCarousel, status, pCarousel->root.rcid );
2657  }
2658  if (status == OC_LOAD_COMPLETED)
2659  {
2660  if (TRUE == pCarousel->bOCLiteOptionsObjectProcessing)
2661  {
2662  ProcessLiteOptionsObjects(idp, pCarousel);
2663  }
2664  else
2665  {
2666  int listCount;
2667  listCount = LLCount( idp->llcCurrLoadRequests );
2668  if (listCount > 1)
2669  {
2670  ProcessLoadRequestsOnCarousel(idp, pCarousel);
2671  }
2672  }
2673  }
2674 
2675  dsmDP3(("exit carouselLoadFinalise\n"));
2676 }
2677 
2678 static void ObjectLoadFinalise( P_DsmCoreInst idp,
2679  P_LoadRequest pLoadRequest )
2680 {
2681  P_DsmObject pDsmObject = pLoadRequest->rlr.target;
2682 
2683  dsmAssert((idp != NULL));
2684  dsmAssert((pLoadRequest != NULL));
2685  dsmAssert((pDsmObject != NULL));
2686  dsmAssert((pLoadRequest->rlr.targetKind == TT_GEN_OBJECT));
2687  dsmAssert((pDsmObject->magic == DSM_OBJECT_MAGIC));
2688 
2689  dsmDP2(("########### ObjectLoadFinalise(status=%d) ###############\n", pLoadRequest->rlr.status));
2690 
2691  /* -- NULL pLoadRequest value in DsmObject since loadRequest is finished
2692  -- with and will subsequently be destroyed */
2693  pDsmObject->r.pLoadRequest = NULL;
2694 
2695  switch (pLoadRequest->rlr.status)
2696  {
2697  case LRS_LOADED:
2698  case LRS_LITE_OPTIONS_LOADED:
2699  dsmDP2(("objectLoaded ModuleId=%d\n",pLoadRequest->pModule->moduleInfo.moduleId));
2700  pDsmObject->pObjCarousel = pLoadRequest->pObjCarousel;
2701  pDsmObject->pModule = pLoadRequest->pModule;
2702  pDsmObject->objectDataOffset =
2703  pLoadRequest->targetObjectOffset;
2704  pDsmObject->objectInfo = pLoadRequest->targetObjectInfo;
2705  pDsmObject->kind =
2706  convertObjectKindStr(
2707  pLoadRequest->targetObjectInfo.objectKind );
2708 
2709  lmSetObjectModuleLoaded( idp, pDsmObject->pModule );
2710 
2711  pDsmObject->status = OBJ_LOAD_COMPLETED;
2712  break;
2713 
2714  case LRS_ABORTED_TIMEOUT:
2715  ERRPRINT("%p", pDsmObject)
2716  pDsmObject->status = OBJ_LOAD_ABORTED_TIMEOUT;
2717  break;
2718 
2719  case LRS_ABORTED_PATH_ERROR:
2720  ERRPRINT("%p", pDsmObject)
2721  pDsmObject->status = OBJ_LOAD_ABORTED_PATH_ERROR;
2722  break;
2723 
2724  case LRS_ABORTED_LOAD_ERROR:
2725  ERRPRINT("%p", pDsmObject)
2726  pDsmObject->status = OBJ_LOAD_ABORTED_ERROR;
2727  break;
2728 
2729  case LRS_ABORTED_BY_REQUESTER:
2730  ERRPRINT("%p", pDsmObject)
2731  pDsmObject->status = OBJ_LOAD_ABORTED_UNLOAD;
2732  break;
2733 
2734  default: /*** INTERNAL ERROR ***/
2735  ERRPRINT("%p", pDsmObject)
2736  pDsmObject->status = OBJ_LOAD_ABORTED_ERROR;
2737  dsmAssert((0));
2738  break;
2739  }
2740 
2741  if (idp->setup.notifyObjectLoadEventFunc)
2742  {
2743  idp->setup.notifyObjectLoadEventFunc( pDsmObject, pDsmObject->status,
2744  pLoadRequest->rlr.usrRef );
2745  }
2746  dsmDP3(("exit ObjectLoadFinalise\n"));
2747 }
2748 
2749 /*
2750 -- Parse directory bindings and create new prefetch dir load for all dirs
2751 --
2752 -- NB. This can be called re-entrantly (max depth = MAX_DIRECTORY_DEPTH).
2753 --
2754 */
2755 static void PreFetchDirLoadFinalise( P_DsmCoreInst idp,
2756  P_LoadRequest pLoadRequest )
2757 {
2758  E_DscError err = CLDSM_OK;
2759 
2760  dsmDP3(("PreFetchDirLoadFinalise()\n"));
2761  dsmAssert((idp != NULL));
2762  dsmAssert((pLoadRequest != NULL));
2763  dsmAssert((pLoadRequest->rlr.targetKind == TT_PREFETCH_DIR_OBJ));
2764 
2765 
2766  /* -- Increment recursion depth counter */
2767  idp->pfdlfCallDepth++;
2768 
2769  /* -- Detect possible 'infinite loops' caused by erroneous circular
2770  -- references in directory hierarchy */
2771  if (idp->pfdlfCallDepth > MAX_DIRECTORY_DEPTH)
2772  {
2773  dsmDP1(("ERROR: PreFetchDirLoadFinalise recursion limit reached: %u\n",
2774  idp->pfrdoCallDepth));
2775  err = CLDSM_ERR_RECURSION_LIMIT_REACHED;
2776  dsmAssert((0));
2777  goto _return;
2778  }
2779 
2780  switch (pLoadRequest->rlr.status)
2781  {
2782  case LRS_LOADED:
2783 
2784  err = PreFetchNewDirsAndDIIsFromLoadedDir( idp, pLoadRequest );
2785 
2786  if (err)
2787  {
2788  dsmDP1(("ERROR: PreFetchDirLoadFinalise: %u\n", err));
2789  /* -- TODO: Provide error returns from finalise funcs? */
2790  /* -- No error return from this function
2791  -- (currently) so handle as a loop error */
2792  err = handleInLoopError( idp, CLDSM_OK, err );
2793  }
2794  break;
2795 
2796  case LRS_ABORTED_TIMEOUT:
2797  case LRS_ABORTED_LOAD_ERROR:
2798  case LRS_ABORTED_BY_REQUESTER:
2799  /* -- Do nothing */
2800  break;
2801 
2802  default: /*** INTERNAL ERROR ***/
2803  dsmAssert((0));
2804  break;
2805  }
2806 
2807 _return:
2808  /* -- Decrement recursion depth counter */
2809  idp->pfdlfCallDepth--;
2810 
2811  dsmDP3(("exit PreFetchDirLoadFinalise\n"));
2812 }
2813 
2814 /* -- CRC CALCULATION */
2815 
2816 
2817 /*----------------------------------------------------------------------------*/
General include file for clDsm library internal definitions.
void DSC_LoadRsqtAbort(P_DsmCoreInst idp, P_RootLoadRqst pLoadRqst)
Force abort (on error) any type of load request Finalise the load request (notify client) and destroy...
Definition: loadRqst.c:157
Header to the loadMgr module.
Header to the sectionTimer module.
BOOLEAN objectDataGetInfo(const MemPtr mpObjectData, ObjectDataInfo_t *pObjInf)
Parse the supplied object data. Verify selected fields. Extract generic information from selected fie...
Definition: object.c:120
Header to the cacheMgr module.
E_DscError CDSM_LoadCarousel(H_DsmCoreInst instance, U16BIT service_id, U32BIT carousel_id, E_SIQueryKind kind, H_DsmCarousel *pclDsmCarouselHandle)
Request load of a DSM-CC Object Carousel (service domain).
Header to the moduleDecompress module.
Header to dsmObject module - functions for managing DSM object heap.
Main API to DSM-CC core layer (provided functions and required callbacks).
void DSC_ModuleDeleteDcTidyUp(P_DsmCoreInst idp, P_Module pModule)
Delete module and destroy parent DC if now empty.
Definition: module.c:388
Header to the sectionFilter module.
Header to the object module - functions/methods accessing data of object messages inside modules...
E_DscError DSC_ModuleAcquireStart(P_DsmCoreInst idp, P_Module pModule, E_SFPriority sfPriority)
Start aquisition of module.
Definition: module.c:204
Header to the 'module' module - Functions/methods for creating/destroying and managing attributes of ...
Defines memory access utils to work with managed (MemMgr) memory.
eader to the clDsmUtils module.
Header to the moduleData module.