Spot the Error

Ok here’s a bog standard piece of Symbian C++. What’s wrong? Hint, its all in the status…

void CConnectionProgressObserver::RunL()
  {
  if (KErrNone == iStatus.Int())
    {
    iConnection.ProgressNotification(iProgressBuf, iStatus);
    SetActive();
    }
  // OnProgressNotificitionL is
  // a callback (void)(TNifProgress, TInt)
  iNotify->OnProgressNotificitionL(iProgressBuf(), iStatus.Int());
  }

Still didn’t get it? Read on…

The problem is, OnProgressNotificationL will always be called with -2147483648 (KRequestPending) for the TInt parameter as long as iStatus.Int() completed without any error, i.e. KErrNone == iStatus.Int().

Why? If you still haven’t guessed, in the above code when we call iConnection.ProgressNotification() which is a call to RConnection::ProgressNotification, the TRequestStatus::iStatus is set to KRequestPending, like any good async method would do. As a result, when we actually call OnProgressNotificitionL(), the value we expect, i.e. the original value of TRequestStatus::iStatus has already mutated! The simple solution is to create a copy of whatever iStatus.Int() returns and call OnProgressNotificitionL() with that.

Bottomline, don’t depend on the value of parameter type once its been passed as an [in/out] parameter to another method.

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s