Brew线程和ISource_Readable回调协同工作的一段示例代码

Brew下要实现的功能:在一个IThread线程中读取IWeb中的数据,并进行些后处理。

因为IWeb是异步的方式,如果IWeb下的ISource中无数据,需要在ISource_Readable中注册一个回调函数,当有数据时调用这个回调函数。所以在IThread线程中的业务代码里必须有一个反复判断IWeb中是否有数据的过程。

并且,因为Brew其实是单线程的,所以在IThread中必须调用如下代码,使当前IThread线程加入到BrewCallback队列中,这样才能响应按键等消息和执行其他的回调函数,避免阻塞对消息循环的访问或者导致界面长事件的不响应。

ISHELL_Resume( pMe->a.m_pIShell,ITHREAD_GetResumeCBK( pMe->pIThread) );

ITHREAD_Suspend( pMe->pIThread );

ISource对象的Readable函数是用于注册当有数据来时要执行的回调函数,因此理想的状态就是在IThread线程里的循环执行过程中,当IWeb中数据读完后有数据来时,会自动调用注册的回调函数,使整个流程能完整进行下去。

下面是主要数据结构,其中musicspliAppletstructWebActionIWeb的。

// A WebAction holds state necessary to perform 1 IWeb transaction

typedef struct _musicsplit musicsplit;

typedef struct WebAction

{

        musicsplit * pParent;          // my parent

        AEECallback          cb;            // how to call me back

        

        IWebResp *           piWResp;       // the answer I get from IWeb

        int                  nBytes;        // count of bytes in response

        } WebAction;

 

struct _musicsplit {

        AEEApplet      a ;           

    AEEDeviceInfo  DeviceInfo;

        .

    IWeb* m_pIWeb;

        char *               m_pszURL;               // "URL" field

        WebAction            m_awa[1];

        ISource*                          m_pISource;

        AEECallback          m_cbimg;

        long                             read_len;

 

        IThread       *pIThread;

        IShell *pIShell;

} ;

 

WebAction也需要有回调函数,在里面获得ISource对象。

 

static void WebAction_GotResp(void *p)

{

        WebAction *pwa = (WebAction *)p;

        musicsplit * pApp = pwa->pParent;

        WebRespInfo *pwri;

        

        pwri = IWEBRESP_GetInfo(pwa->piWResp);         

        pApp->m_pISource = pwri->pisMessage;

        

        CALLBACK_Init(&pApp->m_cbimg,imgCallback,pApp);

}

 

下面是WebAction的初始化函数,初始化URL和回调函数:

static void WebAction_Start(WebAction *pwa, char *pszUrl)

{

        musicsplit * pApp = pwa->pParent;      

        

        CALLBACK_Init(&pwa->cb, WebAction_GotResp, pwa);  

        

        IWEB_GetResponse(pApp->m_pIWeb,

                (pApp->m_pIWeb, &pwa->piWResp, &pwa->cb, pszUrl,

                WEBOPT_HANDLERDATA, pwa,

                WEBOPT_HEADER, "X-Method: GET/r/n",                       

                WEBOPT_END));

}

 

下面是ISource_Readable传入的回调函数,用于读取数据保存到内存中

static void imgCallback(void * p)

{    

        int bytesRead;

        char *x;

        long len = 16384;     

        

        musicsplit * pApp = (musicsplit *)p;

        

        x = (char*)MALLOC(len );

        

        bytesRead = ISOURCE_Read(pApp->m_pISource, x, len);   

        while (bytesRead != ISOURCE_END && bytesRead != ISOURCE_ERROR)

        {

              

              if (bytesRead != ISOURCE_WAIT)

              {

                   DBGPRINTF(x);                     

              }

              else

              {                        

                   ISOURCE_Readable(pApp->m_pISource, &pApp->m_cbimg);

                   return;

              }

              

              bytesRead = ISOURCE_Read(pApp->m_pISource, x, 4);                         

        }

}

 

 

下面是IThread调用的函数,里面有比较耗时的循环,在循环中会调用挂起线程的函数。经过调试,整个过程还是执行的比较好的,ProcessThread函数能够从当前位置暂停,跳到imgCallback中,imgCallback执行完也能回到ProcessThread刚才暂停的位置。

int ProcessThread(IThread *piThread, void *pvCxt)

{

          musicsplit *pMe = (musicsplit *)pvCxt; 

          

          long i,j;

          double dest,tmp;

          char *x;

          long len = 16384;

          int bytesRead;

 

//       for(i=0;i<10000;i++)

          i = 0;

          while(i< 10000)

          {

                     x = (char*)MALLOC(len );

                     bytesRead = ISOURCE_Read(pMe->m_pISource, x, len);

                     while(bytesRead != ISOURCE_WAIT)

                     {

                                     pMe->read_len += bytesRead;

                                     bytesRead = ISOURCE_Read(pMe->m_pISource, x, len);

                     }

                    

                     while (bytesRead != ISOURCE_END && bytesRead != ISOURCE_ERROR)

                     {

                                    

                                     if (bytesRead != ISOURCE_WAIT)

                                     {

                                                //do some work here                                       

                                     }

                                     else

                                     {                            

                                                ISOURCE_Readable(pMe->m_pISource, &pMe->m_cbimg);

                                                break;

                                     }

                                    

                                     bytesRead = ISOURCE_Read(pMe->m_pISource, x, 4);

                                    

                     }

                     FREE(x);

 

                     for(j=0;j<10000;j++)

                     {

                                     tmp =  FSQRT(i*j);

                                     dest = FPOW(tmp, 4);

                                     DBGPRINTF("===========================%d, %d", i,j);

 

                                     ISHELL_Resume( pMe->a.m_pIShell, ITHREAD_GetResumeCBK( pMe->pIThread) );

                                     ITHREAD_Suspend( pMe->pIThread );

                     }

                     i++;                  

          }

          return 1;

}

 

 
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值