Bladeren bron

cmTaskMgr.c : Initial working version.

master
kpl 11 jaren geleden
bovenliggende
commit
881aefdd2d
1 gewijzigde bestanden met toevoegingen van 198 en 69 verwijderingen
  1. 198
    69
      cmTaskMgr.c

+ 198
- 69
cmTaskMgr.c Bestand weergeven

@@ -28,7 +28,8 @@ typedef struct cmTmInst_str
28 28
   cmStatusTmId_t       status;
29 29
   void*                result;
30 30
   unsigned             resultByteCnt;
31
-  cmTaskMgrCtlId_t     ctlId;
31
+  cmTaskMgrCtlId_t     ctlId;          // ctlId must only be written from the client thread
32
+  bool                 deleteOnCompleteFl; // delete this instance when its status indicates that it is killed or complete
32 33
   struct cmTmInst_str* link;
33 34
 } cmTmInst_t;
34 35
 
@@ -45,7 +46,7 @@ typedef struct cmTm_str
45 46
 {
46 47
   cmErr_t             err;
47 48
   cmTmThread_t*       thArray;      // 
48
-  unsigned            threadCnt;        //
49
+  unsigned            threadCnt;    //
49 50
   cmTaskMgrStatusCb_t statusCb;     // 
50 51
   void*               statusCbArg;  // 
51 52
   unsigned            pauseSleepMs;
@@ -56,6 +57,28 @@ typedef struct cmTm_str
56 57
   unsigned            nextInstId;
57 58
 } cmTm_t;
58 59
 
60
+
61
+void  _cmTaskMgrStatusArgSetup(
62
+  cmTaskMgrStatusArg_t* s,
63
+  void*                 arg,
64
+  unsigned              instId,
65
+  cmSelTmId_t           selId,
66
+  cmStatusTmId_t        statusId,
67
+  unsigned              prog,
68
+  const cmChar_t*       msg,
69
+  void*                 result,
70
+  unsigned              resultByteCnt )
71
+{
72
+  s->arg           = arg;
73
+  s->instId        = instId;
74
+  s->selId         = selId;
75
+  s->statusId      = statusId;
76
+  s->prog          = prog;
77
+  s->msg           = msg;
78
+  s->result        = result;
79
+  s->resultByteCnt = resultByteCnt;
80
+}
81
+
59 82
 // WARNING: THIS FUNCTION IS CALLED BY BOTH THE WORKER AND THE MASTER THREAD.
60 83
 cmTmRC_t _cmTmEnqueueStatusMsg0( cmTm_t* p, const cmTaskMgrStatusArg_t* s )
61 84
 {
@@ -67,7 +90,7 @@ cmTmRC_t _cmTmEnqueueStatusMsg0( cmTm_t* p, const cmTaskMgrStatusArg_t* s )
67 90
   msgPtrArray[1] = s->msg==NULL ? "" : s->msg;
68 91
   msgPtrArray[2] = s->result;
69 92
 
70
-  msgSizeArray[0] = sizeof(*s);
93
+  msgSizeArray[0] = sizeof(cmTaskMgrStatusArg_t);
71 94
   msgSizeArray[1] = s->msg==NULL ? 1 : strlen(s->msg)+1;
72 95
   msgSizeArray[2] = s->resultByteCnt;
73 96
 
@@ -92,13 +115,7 @@ cmTmRC_t _cmTmEnqueueStatusMsg1(
92 115
   unsigned        resultByteCnt )
93 116
 {
94 117
   cmTaskMgrStatusArg_t s;
95
-  s.arg           = p->statusCbArg;
96
-  s.instId        = instId;
97
-  s.selId         = selId;
98
-  s.statusId      = statusId;
99
-  s.msg           = msg;
100
-  s.result        = result;
101
-  s.resultByteCnt = resultByteCnt;
118
+  _cmTaskMgrStatusArgSetup(&s,p->statusCbArg,instId,selId,statusId,prog,msg,result,resultByteCnt);
102 119
   return _cmTmEnqueueStatusMsg0(p,&s);
103 120
 }
104 121
 
@@ -124,25 +141,37 @@ bool _cmTmWorkerThreadFunc(void* arg)
124 141
   cmTmThread_t*      trp = (cmTmThread_t*)arg;
125 142
   cmTaskMgrFuncArg_t r;
126 143
 
144
+  r.reserved    = trp;
127 145
   r.arg         = trp->inst->funcArg;
128 146
   r.instId      = trp->inst->instId;
129 147
   r.statusCb    = _cmTmWorkerStatusCb;
130 148
   r.statusCbArg = trp;
131 149
   r.progCnt     = trp->inst->progCnt;
132
-  r.cmdIdPtr    = &trp->inst->ctlId;
133 150
   r.pauseSleepMs= trp->p->pauseSleepMs;
151
+  
152
+  // if the task was paused or killed while it was queued then
153
+  // cmTaskMgrHandleCommand() will do the right thing
154
+  if( cmTaskMgrHandleCommand(&r) != kKillTmId )
155
+  { 
156
+    trp->inst->status = kStartedTmId;
134 157
 
135
-  // Notify the client that the instance has started.
136
-  _cmTmEnqueueStatusMsg1(trp->p,trp->inst->instId,kStatusTmId,kStartedTmId,0,NULL,NULL,0);
158
+    // Notify the client that the instance has started.
159
+    _cmTmEnqueueStatusMsg1(trp->p,trp->inst->instId,kStatusTmId,trp->inst->status,0,NULL,NULL,0);
137 160
 
138
-  // Execute the client provided task function.
139
-  trp->inst->task->func(&r);
161
+    // Execute the client provided task function.
162
+    trp->inst->task->func(&r);
163
+  }
140 164
 
141 165
   // Notify the client that the instance has completed or been killed
142 166
   if( trp->inst->ctlId == kKillTmId )
143
-    _cmTmEnqueueStatusMsg1(trp->p,trp->inst->instId,kStatusTmId,kKilledTmId,0,NULL,NULL,0);
167
+    trp->inst->status = kKilledTmId;
144 168
   else
145
-    _cmTmEnqueueStatusMsg1(trp->p,trp->inst->instId,kStatusTmId,kCompletedTmId,0,NULL,NULL,0);
169
+    trp->inst->status = kCompletedTmId;
170
+
171
+  _cmTmEnqueueStatusMsg1(trp->p,trp->inst->instId,kStatusTmId,trp->inst->status,0,NULL,NULL,0);
172
+
173
+  
174
+  trp->inst = NULL;
146 175
 
147 176
   // Force the thread to go into the 'pause' state when it 
148 177
   // returns to it's internal loop. The master thread recognizes paused
@@ -158,7 +187,7 @@ bool _cmTmMasterThreadFunc(void* arg)
158 187
 {
159 188
   cmTmThread_t* trp = (cmTmThread_t*)arg;
160 189
   cmTm_t*         p = trp->p;
161
-
190
+  
162 191
   while( cmTs1p1cMsgWaiting(p->inQueH) )
163 192
   {
164 193
     unsigned i;
@@ -185,13 +214,15 @@ bool _cmTmMasterThreadFunc(void* arg)
185 214
     
186 215
     // start the thread and wait for it to enter the running state.
187 216
     
188
-    if( cmThreadPause(p->thArray[i].thH,kWaitThFl) != kOkThRC )
217
+    if( cmThreadPause(p->thArray[i].thH,0) != kOkThRC )
189 218
     {
190 219
       /// ??????? HOW DO WE HANDLE ERRORS IN THE MASTER THREAD
191 220
     }
192 221
 
193 222
   }
194 223
 
224
+  cmSleepMs(p->pauseSleepMs);
225
+
195 226
   return true;
196 227
 }
197 228
 
@@ -224,7 +255,6 @@ cmTmInst_t* _cmTmInstFromId( cmTm_t* p, unsigned instId )
224 255
 
225 256
 cmTmRC_t _cmTmInstFree( cmTm_t* p, unsigned instId )
226 257
 {
227
-  cmTmRC_t    rc = kOkTmRC;
228 258
   cmTmInst_t* ip = p->insts;  
229 259
   cmTmInst_t* pp = NULL;
230 260
 
@@ -239,12 +269,12 @@ cmTmRC_t _cmTmInstFree( cmTm_t* p, unsigned instId )
239 269
 
240 270
       cmMemFree(ip->result);
241 271
       cmMemFree(ip);
242
-      break;
272
+      return kOkTmRC;
243 273
     }
244 274
     pp = ip;
245 275
   }
246 276
 
247
-  return rc;
277
+  return cmErrMsg(&p->err,kAssertFailTmRC,"The instance %i could not be found to be deleted.",instId);
248 278
 }
249 279
 
250 280
 
@@ -359,6 +389,8 @@ cmTmRC_t cmTaskMgrCreate(
359 389
     goto errLabel;
360 390
   }
361 391
 
392
+  hp->h = p;
393
+
362 394
  errLabel:
363 395
   return rc;  
364 396
 }
@@ -366,7 +398,7 @@ cmTmRC_t cmTaskMgrCreate(
366 398
 cmTmRC_t cmTaskMgrDestroy( cmTaskMgrH_t* hp )
367 399
 {
368 400
   cmTmRC_t rc = kOkTmRC;
369
-  if( hp!=NULL || cmTaskMgrIsValid(*hp)==false )
401
+  if( hp==NULL || cmTaskMgrIsValid(*hp)==false )
370 402
     return rc;
371 403
 
372 404
   cmTm_t* p = _cmTmHandleToPtr(*hp);
@@ -392,7 +424,7 @@ cmRC_t _cmTmMasterOutQueueCb(void* arg, unsigned msgByteCnt, const void* msgData
392 424
 
393 425
   // This is probably not nesessary since changing the memory  
394 426
   // pointed to by msgDataPtr should be safe even though it is marked as const.
395
-  memcpy(&s,&msgDataPtr,sizeof(s));
427
+  memcpy(&s,msgDataPtr,sizeof(s));
396 428
 
397 429
   // The 'msg' and 'result' data have been serialized after the status record.
398 430
   // The 'msg' is guaranteed to at least contain a terminating zero.
@@ -416,6 +448,7 @@ cmTmRC_t cmTaskMgrOnIdle( cmTaskMgrH_t h )
416 448
   cmTmRC_t rc = kOkTmRC;
417 449
   cmTm_t*  p  = _cmTmHandleToPtr(h);
418 450
 
451
+  // Transmit any msgs waiting to be sent to the client.
419 452
   while( cmTsMp1cMsgWaiting(p->outQueH) )
420 453
   {
421 454
     // calling this function calls: _cmTmMasterOutQueueCb()
@@ -424,8 +457,19 @@ cmTmRC_t cmTaskMgrOnIdle( cmTaskMgrH_t h )
424 457
       rc = cmErrMsg(&p->err,kQueueFailTmRC,"The output queue failed during a dequeue.");
425 458
       goto errLabel;
426 459
     }
460
+  }
461
+
462
+  // Step through the instance list and delete instances that are
463
+  // completed and also marked for deletion.
464
+  cmTmInst_t* ip = p->insts;
465
+  while( ip != NULL )
466
+  {
467
+    cmTmInst_t* np = ip->link;
427 468
 
469
+    if( (ip->status==kCompletedTmId || ip->status==kKilledTmId) && ip->deleteOnCompleteFl )
470
+      _cmTmInstFree(p,ip->instId);
428 471
     
472
+    ip = np;
429 473
   }
430 474
 
431 475
  errLabel:
@@ -436,10 +480,7 @@ bool     cmTaskMgrIsEnabled( cmTaskMgrH_t h )
436 480
 {
437 481
   cmTm_t*  p = _cmTmHandleToPtr(h);
438 482
 
439
-  if( cmThreadState(p->thArray[0].thH) != kPausedThId )
440
-    return false;
441
-
442
-  return true;
483
+  return cmThreadState(p->thArray[0].thH) != kPausedThId;
443 484
 }
444 485
 
445 486
 cmTmRC_t cmTaskMgrEnable(    cmTaskMgrH_t h, bool enableFl )
@@ -489,28 +530,38 @@ cmTmRC_t cmTaskMgrCall(
489 530
   cmTmTask_t* tp = NULL;
490 531
   cmTmInst_t* ip = NULL;
491 532
 
492
-  if((tp = _cmTmTaskFromId(p,taskId)) != NULL )
533
+  if( retInstIdPtr != NULL )
534
+    *retInstIdPtr = cmInvalidId;
535
+
536
+  // locate the task for this instance
537
+  if((tp = _cmTmTaskFromId(p,taskId)) == NULL )
493 538
   {
494 539
     rc = cmErrMsg(&p->err,kInvalidArgTmRC,"Task not found for task id=%i.",taskId);
495 540
     goto errLabel;
496 541
   }
497 542
 
543
+  // allocate a new instance record
498 544
   ip = cmMemAllocZ(cmTmInst_t,1);
499 545
 
546
+  // setupt the instance record
500 547
   ip->instId         = p->nextInstId++;
501 548
   ip->task           = tp;
502 549
   ip->funcArg        = funcArg;
503 550
   ip->progCnt        = progCnt;
504 551
   ip->status         = kQueuedTmId;
505 552
 
553
+  // insert the new instance at the end of the instance list
506 554
   if( p->insts == NULL )
507 555
     p->insts = ip;
508 556
   else
509 557
   {
510 558
     cmTmInst_t* pp = p->insts;
511
-    while( pp != NULL )
559
+    for(; pp != NULL; pp=pp->link )
512 560
       if( pp->link == NULL )
561
+      {
513 562
         pp->link = ip;
563
+        break;
564
+      }
514 565
   }
515 566
 
516 567
 
@@ -521,17 +572,15 @@ cmTmRC_t cmTaskMgrCall(
521 572
     goto errLabel;
522 573
   }
523 574
 
524
-  // notify the client that the instance was enqueued
525
-  // ???????????????
526
-  // (is this ok??? - we are inserting into p->outQueH from the client thread)
527
-  // it would be safe to simply callback directly
528
-  // ???????????????
529
-  if( _cmTmEnqueueStatusMsg1(p,ip->instId,kStatusTmId,kQueuedTmId,0,NULL,NULL,0) != kOkTmRC )
530
-  {
531
-    cmErrMsg(&p->err,kQueueFailTmRC,"The 'queued' status update message failed to enqueue.");
532
-    goto errLabel;
533
-  }
575
+  // set the returned instance id
576
+  if( retInstIdPtr != NULL )
577
+    *retInstIdPtr = ip->instId;
534 578
 
579
+  // notify the client that the instance was enqueued
580
+  cmTaskMgrStatusArg_t s;
581
+  _cmTaskMgrStatusArgSetup(&s,p->statusCbArg,ip->instId,kStatusTmId,kQueuedTmId,0,NULL,NULL,0);
582
+  
583
+  p->statusCb( &s );
535 584
   
536 585
  errLabel:
537 586
   return rc;
@@ -549,9 +598,34 @@ cmTmRC_t cmTaskMgrTaskCtl( cmTaskMgrH_t h, unsigned instId, cmTaskMgrCtlId_t ctl
549 598
     goto errLabel;
550 599
   }
551 600
 
552
-  // once the ctl id is set to kKillTmId don't allow it to change
553
-  if( ip->ctlId != kKillTmId )
554
-    ip->ctlId = ctlId;
601
+  // Once an instance ctlId is set to kKillTmId don't allow it to change.
602
+  if( ip->ctlId == kKillTmId )
603
+    return rc;
604
+
605
+  switch(ctlId )
606
+  {
607
+    case kNoneTmId:
608
+      break;
609
+
610
+    case kStartTmId:
611
+      // Acting on a 'start' cmd only makes sense if the previous command was 'pause'
612
+      if( ip->ctlId == kPauseTmId )
613
+        ip->ctlId = kStartTmId;
614
+      break;
615
+
616
+    case kPauseTmId:
617
+
618
+      // Acting on a 'pause' command only makes sense if this is the first command
619
+      // or the previous command was a 'start'
620
+      if( ip->ctlId == kNoneTmId || ip->ctlId == kStartTmId )
621
+        ip->ctlId = kPauseTmId;
622
+      break;
623
+
624
+    case kKillTmId:
625
+      ip->ctlId = kKillTmId;
626
+      break;
627
+  }
628
+
555 629
 
556 630
  errLabel:
557 631
   return rc;
@@ -604,32 +678,81 @@ unsigned    cmTaskMgrResultByteCount( cmTaskMgrH_t h, unsigned instId )
604 678
   return ip->resultByteCnt;
605 679
 }
606 680
 
607
-cmTmRC_t    cmTaskMgrResultDelete(    cmTaskMgrH_t h, unsigned instId )
681
+cmTmRC_t    cmTaskMgrInstDelete(    cmTaskMgrH_t h, unsigned instId )
608 682
 {
609 683
   cmTmRC_t rc = kOkTmRC;
610 684
   cmTm_t*  p  = _cmTmHandleToPtr(h);
685
+  cmTmInst_t* ip = NULL;
611 686
 
612
-  if((rc = _cmTmInstFree(p,instId)) != kOkTmRC )
613
-    rc = cmErrMsg(&p->err,kOpFailTmRC,"The instace delete failed on instance id %i.",instId);
687
+  if((ip = _cmTmInstFromId(p,instId)) == NULL )
688
+  {
689
+    cmErrMsg(&p->err,kInvalidArgTmRC,"The task instance associated with id %i could not be found.",instId);
690
+    return 0;
691
+  }
692
+
693
+  ip->deleteOnCompleteFl = true;
614 694
 
615 695
   return rc;
616 696
 }
617 697
 
618 698
 
699
+cmTaskMgrCtlId_t _cmTaskMgrHelper( cmTaskMgrFuncArg_t* a, unsigned prog, cmStatusTmId_t statusId )
700
+{
701
+  cmTaskMgrStatusArg_t s;
702
+
703
+  _cmTaskMgrStatusArgSetup(
704
+    &s,
705
+    a->statusCbArg,
706
+    a->instId,
707
+    statusId == kInvalidTmId ? kProgTmId    : kStatusTmId,
708
+    statusId == kInvalidTmId ? kStartedTmId : statusId,
709
+    statusId == kInvalidTmId ? prog         : 0,
710
+    NULL,NULL,0);
711
+
712
+  a->statusCb(&s);
713
+
714
+  return cmTaskMgrHandleCommand(a);
715
+}
716
+
619 717
 cmTaskMgrCtlId_t cmTaskMgrHandleCommand( cmTaskMgrFuncArg_t* a )
620 718
 {
719
+  cmTmThread_t* trp = a->reserved;
621 720
 
622
-  while( *(a->cmdIdPtr) == kPauseTmId )
721
+  while( trp->inst->ctlId == kPauseTmId )
623 722
   {
624
-    // ????????
625
-    // maybe we should send a status code to notify the client that the instance has paused.
626
-    ///
723
+    // change the instance status to 'paused'.
724
+    trp->inst->status = kPausedTmId;
725
+
726
+    // notify the client of the change in state
727
+    cmTaskMgrSendStatus(a,kPausedTmId);
728
+
729
+    // sleep the thread for pauseSleepMs milliseconds
627 730
     cmSleepMs(a->pauseSleepMs);
731
+
732
+    // if the task was unpaused while we slept
733
+    if( trp->inst->ctlId == kStartTmId )
734
+    {
735
+      // change the instance status to 'started'.
736
+      trp->inst->status = kStartedTmId;
737
+
738
+      // notify the client of the change in state
739
+      cmTaskMgrSendStatus(a,kStartedTmId);
740
+    }
628 741
   }
629 742
 
630
-  return *(a->cmdIdPtr);
743
+  // if ctlId==kKillTmId then the status update will be handled 
744
+  // when the task custom function returns in  _cmTmWorkerThreadFunc()
745
+
746
+  return trp->inst->ctlId;
631 747
 }
632 748
 
749
+cmTaskMgrCtlId_t cmTaskMgrSendStatus( cmTaskMgrFuncArg_t* a, cmStatusTmId_t statusId )
750
+{ return _cmTaskMgrHelper(a,0,statusId); }
751
+
752
+cmTaskMgrCtlId_t cmTaskMgrSendProgress( cmTaskMgrFuncArg_t* a, unsigned prog )
753
+{ return _cmTaskMgrHelper(a,prog,kInvalidTmId);  }
754
+
755
+
633 756
 //-----------------------------------------------------------------------------
634 757
 
635 758
 enum { kMaxTestInstCnt = 3 };
@@ -647,7 +770,7 @@ typedef struct cmTmTestApp_str
647 770
 
648 771
 void _cmTmTestReportStatus( cmRpt_t* rpt, const cmTaskMgrStatusArg_t* s )
649 772
 {
650
-  cmRptPrintf(rpt,"%i ",s->instId );
773
+  cmRptPrintf(rpt,"inst:%i ",s->instId );
651 774
 
652 775
   switch( s->selId )
653 776
   {
@@ -658,7 +781,6 @@ void _cmTmTestReportStatus( cmRpt_t* rpt, const cmTaskMgrStatusArg_t* s )
658 781
         {
659 782
           case kInvalidTmId:       label="<Invalid>"; break;
660 783
           case kQueuedTmId:        label="Queued";  break;
661
-          case kQueuedPausedTmId:  label="Queued-Paused."; break;
662 784
           case kStartedTmId:       label="Started"; break;
663 785
           case kCompletedTmId:     label="Completed"; break;
664 786
           case kKilledTmId:        label="Killed"; break;
@@ -685,6 +807,7 @@ void _cmTmTestReportStatus( cmRpt_t* rpt, const cmTaskMgrStatusArg_t* s )
685 807
 
686 808
 }
687 809
 
810
+// Test client status callback function.
688 811
 void _cmTmTestStatusCb( const cmTaskMgrStatusArg_t* s  )
689 812
 {
690 813
    // s.arg set from cmTaskMgrCreate( ..., statusCbArg, ...);
@@ -703,26 +826,21 @@ void _cmTmTestStatusCb( const cmTaskMgrStatusArg_t* s  )
703 826
 }
704 827
 
705 828
 
829
+// Test worker function.
706 830
 void _cmTmTestFunc(cmTaskMgrFuncArg_t* arg )
707 831
 {
708
-  cmTaskMgrStatusArg_t s;
709
-  memset(&s,0,sizeof(s));
710
-  s.arg           = arg->statusCbArg;
711
-  s.instId        = arg->instId;
712
-  s.selId         = kProgTmId;
713
-  s.statusId      = kStartedTmId;
714
-  s.prog          = 0;
715
-  s.msg           = NULL;
716
-  s.result        = NULL;
717
-  s.resultByteCnt = 0;
718
-
719
-  for(; s.prog<arg->progCnt; ++s.prog)
832
+
833
+  unsigned prog = 0;
834
+
835
+  for(; prog<arg->progCnt; ++prog)
720 836
   {
721 837
     if( cmTaskMgrHandleCommand(arg) == kKillTmId )
722 838
       break;
723 839
 
724 840
     cmSleepMs(1000); 
725
-    arg->statusCb(&s);
841
+
842
+    if( cmTaskMgrSendProgress(arg,prog) == kKillTmId )
843
+      break;
726 844
   }
727 845
   
728 846
 }
@@ -745,7 +863,7 @@ cmTmRC_t cmTaskMgrTest(cmCtx_t* ctx)
745 863
   app.err = &ctx->err;
746 864
 
747 865
   // create the task mgr
748
-  if( cmTaskMgrCreate( ctx,&tmH,_cmTmTestStatusCb,&app,threadCnt,queueByteCnt,pauseSleepMs) != kOkTmRC )
866
+   if( cmTaskMgrCreate( ctx,&tmH,_cmTmTestStatusCb,&app,threadCnt,queueByteCnt,pauseSleepMs) != kOkTmRC )
749 867
   {
750 868
     rc = cmErrMsg(&ctx->err,kTestFailTmRC,"Task mgr create failed.");
751 869
     goto errLabel;
@@ -760,16 +878,24 @@ cmTmRC_t cmTaskMgrTest(cmCtx_t* ctx)
760 878
 
761 879
 
762 880
   // go into interactive mode
881
+  printf("q=quit e=enable c=call i=idle\n");
763 882
   while((c = getchar()) != 'q')
764 883
   {
765 884
     switch(c)
766 885
     {
886
+      case 'i':
887
+        cmTaskMgrOnIdle(tmH);
888
+        cmRptPrintf(&ctx->rpt,"idled\n");
889
+        break;
890
+
767 891
       case 'e':
768 892
         {
769 893
           // toggle the enable state of the task mgr.
770
-          bool fl = cmTaskMgrIsEnabled(tmH);
771
-          if( cmTaskMgrEnable(tmH,!fl) != kOkTmRC )
894
+          bool fl = !cmTaskMgrIsEnabled(tmH);
895
+          if( cmTaskMgrEnable(tmH,fl) != kOkTmRC )
772 896
             rc = cmErrMsg(&ctx->err,kTestFailTmRC,"Test enable failed.");
897
+          else
898
+            cmRptPrintf(&ctx->rpt,"%s\n", fl ? "enabled" : "disabled" );
773 899
         }
774 900
         break;
775 901
 
@@ -781,7 +907,10 @@ cmTmRC_t cmTaskMgrTest(cmCtx_t* ctx)
781 907
             if( cmTaskMgrCall( tmH, taskId, funcArg, progCnt, &app.insts[nextInstId].instId ) != kOkTmRC )
782 908
               rc = cmErrMsg(&ctx->err,kTestFailTmRC,"Test call failed.");            
783 909
             else
910
+            {
784 911
               ++nextInstId;
912
+              cmRptPrintf(&ctx->rpt,"called\n");
913
+            }
785 914
           }
786 915
     }
787 916
   }

Laden…
Annuleren
Opslaan