Advertisement
Guest User

BonD_FSUSB2i-20160219_mod_20180228.diff

a guest
Feb 27th, 2018
219
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 19.23 KB | None | 0 0
  1. diff -uPr BonD_FSUSB2i-20160219_org3/src/tsthread.c BonD_FSUSB2i-20160219_mod3/src/tsthread.c
  2. --- BonD_FSUSB2i-20160219_org3/src/tsthread.c   2016-02-18 20:21:28.000000000 +0900
  3. +++ BonD_FSUSB2i-20160219_mod3/src/tsthread.c   2018-02-28 00:14:57.000000000 +0900
  4. @@ -1,8 +1,3 @@
  5. -/* fsusb2i   (c) 2015-2016 trinity19683
  6. -  TS USB I/O thread (MS-Windows)
  7. -  tsthread.c
  8. -  2016-02-18
  9. -*/
  10.  #include "stdafx.h"
  11.  #include <errno.h>
  12.  #include <string.h>
  13. @@ -14,12 +9,15 @@
  14.  #include "tsbuff.h"
  15.  #include "tsthread.h"
  16.  
  17. +//# number of compensated read only bytes before the buffer busy memory area
  18. +#define TS_DeadZone  (TS_BufSize/2) //1835008
  19. +
  20.  #define ROUNDUP(n,w) (((n) + (w)) & ~(unsigned)(w))
  21.  
  22.  struct TSIO_CONTEXT {
  23.     OVERLAPPED ol;
  24.     int index;
  25. -
  26. +   DWORD bytesRead;
  27.  };
  28.  
  29.  struct tsthread_param {
  30. @@ -35,198 +33,362 @@
  31.     int buff_num;
  32.     int buff_push;
  33.     int buff_pop;
  34. +   int total_submit ;
  35.     struct TSIO_CONTEXT ioContext[TS_MaxNumIO];
  36. -   HANDLE hTsEvent;
  37. -
  38. +   HANDLE hTsEvents[TS_MaxNumIO*2-1] ;
  39. +   HANDLE hTsAvailable,hTsRead,hTsRestart ;
  40. +   CRITICAL_SECTION csTsRead;
  41.  };
  42.  
  43. -
  44. -static int submitURB(const tsthread_ptr tptr)
  45. +static void tsthread_purgeURB(const tsthread_ptr ptr)
  46.  {
  47. -   //# isochronous URB request
  48. -   struct tsthread_param* const ps = tptr;
  49. -   DWORD i, dRet = 0;
  50. +   struct tsthread_param* const ps = ptr;
  51. +   int i;
  52.  
  53. -   for(i = 0; i < TS_MaxNumIO; i++) {
  54. -       struct TSIO_CONTEXT* const pContext = &ps->ioContext[i];
  55. -       BOOL bRet;
  56. -       if(0 <= pContext->index) continue;
  57. -
  58. -       ZeroMemory( &pContext->ol, sizeof(OVERLAPPED));
  59. -       pContext->ol.hEvent = ps->hTsEvent;
  60. -       pContext->index = ps->buff_push;
  61. -       if(ps->pUSB->endpoint & 0x100) { //# Isochronous
  62. -
  63. -           bRet = FALSE;
  64. -           dRet = ERROR_INVALID_FUNCTION;
  65. -           tsthread_stop(ps);
  66. +   WinUsb_AbortPipe(ps->pUSB->fd, ps->pUSB->endpoint & 0xFF);
  67.  
  68. -       }
  69. -       else {
  70. -           ps->actual_length[ps->buff_push] = -2;
  71. -           bRet = WinUsb_ReadPipe(ps->pUSB->fd, ps->pUSB->endpoint & 0xFF, ps->buffer + (ps->buff_push * ps->buff_unitSize), ps->buff_unitSize, NULL, &(pContext->ol));
  72. -           dRet = GetLastError();
  73. -       }
  74. -       if (FALSE == bRet && ERROR_IO_PENDING != dRet) {
  75. -           warn_info(dRet, "submitURB failed");
  76. -           pContext->index = -1;
  77. -       }
  78. -       else {
  79. -           int next_index = ps->buff_push;
  80. -           next_index++;
  81. -           ps->buff_push = (next_index < ps->buff_num) ? next_index : 0;
  82. -           dRet = 0;
  83. -       }
  84. +   EnterCriticalSection(&ps->csTsRead);
  85. +
  86. +   if(ps->total_submit>0) {
  87.  
  88. -       if (bRet) {
  89. -           //# completed (nowait)
  90. -           SetEvent(ps->hTsEvent);
  91. +       for (i = 0;i < TS_MaxNumIO;i++) {
  92. +           struct TSIO_CONTEXT* pContext = &ps->ioContext[i];
  93. +           if(pContext->index>=0) {
  94. +               ResetEvent(pContext->ol.hEvent);
  95. +               pContext->index=-1 ;
  96. +           }
  97.         }
  98. -       if(dRet) break;
  99. +
  100. +       ps->total_submit = 0;
  101. +
  102.     }
  103.  
  104. -   return dRet;
  105. +   for (i = 0;i < ps->buff_num;i++)
  106. +       ps->actual_length[i]=-1 ;
  107. +
  108. +   ps->buff_pop = ps->buff_push ;
  109. +
  110. +   LeaveCriticalSection(&ps->csTsRead);
  111. +
  112. +   WinUsb_FlushPipe(ps->pUSB->fd, ps->pUSB->endpoint & 0xFF);
  113.  }
  114.  
  115. -static int reapURB(const tsthread_ptr tptr)
  116. +static unsigned int tsthread_bulkURB(struct tsthread_param* const ps)
  117.  {
  118. -   struct tsthread_param* const ps = tptr;
  119. -   DWORD i, countURB = 0;
  120. +   //# number of the prefetching buffer busy area that shouldn't be submitted
  121. +   const int POPDELTA = (TS_DeadZone+ps->buff_unitSize-1)/ps->buff_unitSize;
  122.  
  123. -   for(i = 0; i < TS_MaxNumIO; i++) {
  124. -       struct TSIO_CONTEXT* const pContext = &ps->ioContext[i];
  125. -       BOOL bRet;
  126. -       DWORD dRet, bytesRead = 0;
  127. -       if(0 > pContext->index) continue;
  128. -
  129. -       bRet = WinUsb_GetOverlappedResult( ps->pUSB->fd, &(pContext->ol), &bytesRead, FALSE );
  130. -       dRet = GetLastError();
  131. -       if(FALSE == bRet && ERROR_IO_INCOMPLETE == dRet) {
  132. -           //# incomplete
  133. -           countURB++;
  134. -       }else{
  135. -           int* const   pLen = &(ps->actual_length[pContext->index]);
  136. -           if(ps->pUSB->endpoint & 0x100) { //# Isochronous
  137. +   int ri=0; //# the circular index based ioContext cursor for reaping
  138. +   int si=0; //# the circular index based ioContext cursor for submitting
  139. +   int next_wait_index=0 ;
  140. +   BOOL bRet ;
  141. +   DWORD dRet=0 ;
  142. +
  143. +   //# bulk loop
  144. +   while(!(ps->flags&0x02)) {
  145.  
  146. +       struct TSIO_CONTEXT* pContext = &ps->ioContext[ri];
  147. +       BOOL isTimeout = FALSE;
  148. +       BOOL isSync = FALSE;
  149. +
  150. +       if(WaitForSingleObject(ps->hTsRestart,0)==WAIT_OBJECT_0) {
  151. +           tsthread_purgeURB(ps) ;
  152. +           ResetEvent(ps->hTsRestart) ;
  153. +           continue;
  154. +       }
  155. +
  156. +       if (!(ps->flags & 0x01)) {
  157. +           WaitForSingleObject(ps->hTsAvailable, TS_PollTimeout) ;
  158. +           continue ;
  159. +       }
  160. +
  161. +       if (ps->pUSB->endpoint & 0x100) { //# Isochronous
  162. +           if(ps->flags & 0x01) {
  163. +               tsthread_stop(ps);
  164. +               continue ;
  165.             }
  166. -           else {
  167. -               if (bRet) {
  168. -                   //# success
  169. -                   if (ps->buff_unitSize < bytesRead) {
  170. -                       warn_info(bytesRead, "reapURB overflow");
  171. -                       bytesRead = ps->buff_unitSize;
  172. +       }
  173. +
  174. +       if(ps->total_submit>0) {
  175. +
  176. +           if(pContext->index>=0) {
  177. +
  178. +               DWORD bytesRead= 0;
  179. +
  180. +               //# poll
  181. +               if (WaitForSingleObject(ps->hTsEvents[ri], 0) == WAIT_OBJECT_0) {
  182. +                   isSync = TRUE;
  183. +                   if(ri==next_wait_index) {
  184. +                       if (++next_wait_index >= TS_MaxNumIO)
  185. +                           next_wait_index -= TS_MaxNumIO ;
  186. +                   }
  187. +               }else if (ri == next_wait_index) {
  188. +                   dRet = WaitForMultipleObjects(ps->total_submit, &ps->hTsEvents[ri] , FALSE, TS_PollTimeout );
  189. +                   if(WAIT_OBJECT_0 <= dRet&&dRet < WAIT_OBJECT_0+ps->total_submit) {
  190. +                       if(dRet==WAIT_OBJECT_0) isSync = TRUE ;
  191. +                       next_wait_index = (dRet - WAIT_OBJECT_0) + ri + 1 ;
  192. +                       if (next_wait_index >= TS_MaxNumIO)
  193. +                           next_wait_index -= TS_MaxNumIO ;
  194. +                   }else if(WAIT_TIMEOUT==dRet)
  195. +                       isTimeout=TRUE ;
  196. +                   else {
  197. +                       dRet = GetLastError();
  198. +                       warn_info(dRet,"poll failed");
  199. +                       break;
  200. +                   }
  201. +               }else
  202. +                   isTimeout=TRUE ;
  203. +
  204. +               //# reap
  205. +               bytesRead=pContext->bytesRead ;
  206. +               if(bytesRead) {
  207. +                   bRet = TRUE ; dRet = 0 ;
  208. +               }else {
  209. +                   if(isSync||HasOverlappedIoCompleted(&(pContext->ol))) {
  210. +                       bRet = WinUsb_GetOverlappedResult( ps->pUSB->fd, &(pContext->ol), &bytesRead, isSync);
  211. +                       dRet = GetLastError();
  212. +                   }else {
  213. +                       bRet = FALSE ;
  214. +                       dRet = ERROR_IO_INCOMPLETE ;
  215.                     }
  216. -                   pLen[0] = bytesRead;
  217. -                   //dmsgn("reapURB%u=%d, ",i,bytesRead);
  218.                 }
  219. -               else {
  220. -                   //# failed
  221. -                   pLen[0] = 0;
  222. -                   warn_msg(dRet, "reapURB%u", i);
  223. +               if (ps->buff_unitSize < bytesRead) {
  224. +                   warn_info(bytesRead, "reapURB overflow");
  225. +                   bytesRead = ps->buff_unitSize;
  226.                 }
  227. +               if(bRet) {
  228. +                   if (ps->pUSB->endpoint & 0x100) bytesRead = 0;
  229. +                   ps->actual_length[pContext->index] = bytesRead;
  230. +                   if(bytesRead) SetEvent(ps->hTsAvailable) ;
  231. +                   ps->total_submit--;
  232. +                   ResetEvent(ps->hTsEvents[ri]);
  233. +                   pContext->index=-1 ;
  234. +                   isTimeout = FALSE;
  235. +               }else {
  236. +                   if(ERROR_IO_INCOMPLETE == dRet && !(ps->pUSB->endpoint & 0x100)) {
  237. +                       //SetEvent(ps->hTsEvents[ri]);
  238. +                       isTimeout=TRUE ;
  239. +                   }
  240. +                   else {
  241. +                       if( ERROR_OPERATION_ABORTED==dRet||
  242. +                           ERROR_SEM_TIMEOUT==dRet||
  243. +                           (ps->pUSB->endpoint & 0x100) )
  244. +                               bytesRead = 0;
  245. +                       //# failed
  246. +                       ps->actual_length[pContext->index] = bytesRead;
  247. +                       warn_msg(dRet, "reapURB%u failed", ri);
  248. +                       ps->total_submit--;
  249. +                       ResetEvent(ps->hTsEvents[ri]);
  250. +                       pContext->index = -1;
  251. +                       isTimeout = FALSE;
  252. +                   }
  253. +               }
  254. +
  255.             }
  256. -           pContext->index = -1;
  257. +
  258.         }
  259. +
  260. +       if(!ps->total_submit) {
  261. +           //# I/O stall
  262. +           next_wait_index = si = ri ;
  263. +           isTimeout=TRUE ;
  264. +       }
  265. +
  266. +       if(ps->total_submit<TS_MaxNumIO) {
  267. +
  268. +           //# submit
  269. +           if(ps->flags & 0x01) {
  270. +               void *buffer;
  271. +               DWORD lnTransfered;
  272. +               int num_empties,max_empties;
  273. +               int last_state;
  274. +               dRet = 0;bRet = FALSE;
  275. +               //# calculate the real maximum number of submittable empties
  276. +               EnterCriticalSection(&ps->csTsRead) ;
  277. +               last_state = ps->actual_length[ps->buff_pop] ;
  278. +               if(ps->buff_push==ps->buff_pop)
  279. +                   max_empties =
  280. +                       last_state>0||last_state==-2 ? 0 : ps->buff_num ;
  281. +               else
  282. +                   max_empties = ps->buff_push<ps->buff_pop ?
  283. +                       ps->buff_pop-ps->buff_push :
  284. +                       ps->buff_num-ps->buff_push + ps->buff_pop ;
  285. +               ResetEvent(ps->hTsRead);
  286. +               LeaveCriticalSection(&ps->csTsRead) ;
  287. +               max_empties -= POPDELTA; //# subtract deadzone
  288. +               //# summary amount of empties
  289. +               num_empties=TS_MaxNumIO-ps->total_submit;
  290. +               if(num_empties>max_empties) {
  291. +                   num_empties = max_empties ;
  292. +                   #if 1
  293. +                   if(num_empties<=0) {
  294. +                       //# in the dead zone
  295. +                       if(last_state>0) {
  296. +                           HANDLE events[3];
  297. +                           events[0]=ps->hTsRead;
  298. +                           events[1]=ps->hTsRestart ;
  299. +                           events[2]=ps->hTsEvents[ri+(isTimeout?0:1)] ;
  300. +                           //# wait for reading buffer...
  301. +                           WaitForMultipleObjects(3, events , FALSE, TS_PollTimeout );
  302. +                       }
  303. +                   }
  304. +                   #endif
  305. +               }
  306. +               //# submit to empties
  307. +               while(num_empties-->0) {
  308. +                   pContext = &ps->ioContext[si];
  309. +                   if (pContext->index>=0) break ; //# I/O busy
  310. +                   if (WaitForSingleObject(ps->hTsRestart,0)==WAIT_OBJECT_0) break;
  311. +                   if (WaitForSingleObject(ps->hTsEvents[ri+(isTimeout?0:1)],0)==WAIT_OBJECT_0) break;
  312. +                   if (!(ps->flags & 0x01)) break;
  313. +                   if (ps->pUSB->endpoint & 0x100) { //# Isochronous
  314. +                       //tsthread_stop(ps);
  315. +                       break;
  316. +                   }
  317. +                   if(ps->actual_length[ps->buff_push]>0||ps->actual_length[ps->buff_push]==-2)
  318. +                       break ; //# buffer busy
  319. +                   else {
  320. +                       buffer = ps->buffer + (ps->buff_push * ps->buff_unitSize) ;
  321. +                       last_state =  ps->actual_length[ps->buff_push] ;
  322. +                       ps->actual_length[ps->buff_push] = -2;
  323. +                   }
  324. +                   pContext->index = ps->buff_push;
  325. +                   pContext->bytesRead = 0 ;
  326. +                   ZeroMemory(&pContext->ol,sizeof(OVERLAPPED));
  327. +                   pContext->ol.hEvent = ps->hTsEvents[si];
  328. +                   lnTransfered = 0;
  329. +                   ResetEvent(pContext->ol.hEvent);
  330. +                   bRet = WinUsb_ReadPipe(ps->pUSB->fd, ps->pUSB->endpoint & 0xFF,
  331. +                       buffer, ps->buff_unitSize, &lnTransfered, &(pContext->ol));
  332. +                   dRet = GetLastError();
  333. +                   if (FALSE == bRet && ERROR_IO_PENDING != dRet) {
  334. +                       warn_info(dRet, "submitURB failed");
  335. +                       ps->actual_length[ps->buff_push] = last_state;
  336. +                       ResetEvent(ps->hTsEvents[si]);
  337. +                       pContext->index = -1;
  338. +                   }else {
  339. +                       if(ps->buff_push+1>=ps->buff_num)
  340. +                           ps->buff_push=0;
  341. +                       else
  342. +                           ps->buff_push++;
  343. +                       if(bRet) {
  344. +                           pContext->bytesRead = lnTransfered ;
  345. +                           SetEvent(ps->hTsEvents[si]) ;
  346. +                       }
  347. +                       ps->total_submit++;
  348. +                       bRet=TRUE ; dRet = 0;
  349. +                   }
  350. +                   if(dRet) break ;
  351. +                   if(bRet && ++si >= TS_MaxNumIO) si=0;
  352. +               }
  353. +               //if(dRet) break ;
  354. +           }
  355. +
  356. +       }
  357. +
  358. +       if(isTimeout) continue ;
  359. +       if(++ri >= TS_MaxNumIO) ri=0 ;
  360. +
  361.     }
  362.  
  363. -   return countURB;
  364. +   //# dispose
  365. +   tsthread_purgeURB(ps);
  366. +
  367. +   return dRet ;
  368.  }
  369.  
  370.  /* TS thread function issues URB requests. */
  371.  static unsigned int __stdcall tsthread(void* const param)
  372.  {
  373.     struct tsthread_param* const ps = param;
  374. +   unsigned int result = 0;
  375. +
  376.     ps->buff_push = 0;
  377.  
  378. -   for(;;) {
  379. -       DWORD dRet;
  380. -       if(ps->flags & 0x01) {
  381. -           //# continue to issue a new URB request
  382. -           submitURB(ps);
  383. -       }
  384. -       if(ps->flags & 0x02) {
  385. -           //# canceled
  386. -           reapURB(ps);
  387. -           break;
  388. -       }
  389. +   result = tsthread_bulkURB(ps);
  390.  
  391. -       dRet = WaitForSingleObject( ps->hTsEvent , TS_PollTimeout );
  392. -       if(WAIT_OBJECT_0 == dRet || WAIT_TIMEOUT == dRet) {
  393. -           if(reapURB(ps) < 0) break;
  394. -           //# timeout
  395. -           if(WAIT_TIMEOUT == dRet && ps->flags & 0x01) {
  396. -               dmsg("poll timeout");
  397. -           }
  398. -       }else{
  399. -           dRet = GetLastError();
  400. -           warn_info(dRet,"poll failed");
  401. -           break;
  402. -       }
  403. -   }
  404.     _endthreadex( 0 );
  405. -   return 0;
  406. +   return result ;
  407.  }
  408.  
  409.  /* public function */
  410.  
  411. -int tsthread_create(tsthread_ptr* const tptr, const struct usb_endpoint_st* const pusbep)
  412. +int tsthread_create( tsthread_ptr* const tptr,
  413. +                    const struct usb_endpoint_st* const pusbep
  414. +                  )
  415.  {
  416.     struct tsthread_param* ps;
  417.     DWORD dwRet, i;
  418.  
  419. -   {//#
  420. -       const unsigned param_size  = ROUNDUP(sizeof(struct tsthread_param), 0xF);
  421. -       const unsigned buffer_size = ROUNDUP(TS_BufSize ,0xF);
  422. -       const unsigned unitSize = ROUNDUP(pusbep->xfer_size ,0x1FF);
  423. +   { //#
  424. +       const unsigned param_size = ROUNDUP( sizeof( struct tsthread_param ), 0xF );
  425. +       const unsigned buffer_size = ROUNDUP( TS_BufSize , 0xF );
  426. +       const unsigned unitSize = ROUNDUP( pusbep->xfer_size, 0x1FF ) ;
  427.         const unsigned unitNum = TS_BufSize / unitSize;
  428. -       const unsigned actlen_size = sizeof(int) * unitNum;
  429. +       const unsigned actlen_size = sizeof( int ) * unitNum;
  430.         char *ptr, *buffer_ptr;
  431. -       unsigned totalSize = param_size + actlen_size + buffer_size;
  432. +       unsigned totalSize = param_size + actlen_size + buffer_size ;
  433.         ptr = uHeapAlloc( totalSize );
  434. -       if(NULL == ptr) {
  435. +       if ( NULL == ptr ) {
  436.             dwRet = GetLastError();
  437. -           warn_msg(dwRet,"failed to allocate TS buffer");
  438. +           warn_msg( dwRet, "failed to allocate TS buffer" );
  439.             return -1;
  440.         }
  441.         buffer_ptr = ptr;
  442.         ptr += buffer_size;
  443. -       ps = (struct tsthread_param*) ptr;
  444. +       ps = ( struct tsthread_param* ) ptr;
  445.         ps->buffer = buffer_ptr;
  446.         ptr += param_size;
  447. -       ps->actual_length = (int*)ptr;
  448. +       ps->actual_length = ( int* ) ptr;
  449.         //ptr += actlen_size;
  450.         ps->buff_unitSize = unitSize;
  451.         ps->buff_num = unitNum;
  452. -       ps->actual_length[0] = -1;   //# the first block is not-used
  453. -
  454. +       if ( actlen_size ) {
  455. +           for ( i = 0;i < unitNum;i++ )
  456. +               ps->actual_length[ i ] = -1;   //# rest all values to empty
  457. +       }
  458.     }
  459.     ps->pUSB = pusbep;
  460.     ps->flags = 0;
  461.     ps->buff_pop = 0;
  462. -  
  463. -   for(i = 0; i < TS_MaxNumIO; i++) {
  464. -       ps->ioContext[i].index = -1;    //# mark it unused
  465. +   ps->total_submit = 0;
  466. +
  467. +   for ( i = 0; i < TS_MaxNumIO; i++ ) {
  468. +       ps->ioContext[ i ].index = -1;    //# mark it unused
  469. +       ps->hTsEvents[ i ] = CreateEvent( NULL, TRUE, FALSE, NULL );
  470. +       ZeroMemory( &ps->ioContext[ i ].ol, sizeof( OVERLAPPED ) );
  471. +       ps->ioContext[ i ].ol.hEvent = ps->hTsEvents[ i ];
  472.     }
  473. -   ps->hTsEvent = CreateEvent ( NULL, FALSE, TRUE, NULL );
  474. +
  475. +   //# it arranges for event handles to look like circular buffer
  476. +   for ( i = 0; i < TS_MaxNumIO - 1; i++ ) {
  477. +       ps->hTsEvents[ i + TS_MaxNumIO ] = ps->hTsEvents[ i ];
  478. +   }
  479. +   ps->hTsAvailable = CreateEvent( NULL, FALSE, FALSE, NULL );
  480. +   ps->hTsRead = CreateEvent( NULL, FALSE, FALSE, NULL );
  481. +   ps->hTsRestart = CreateEvent( NULL, TRUE, FALSE, NULL );
  482. +   InitializeCriticalSection(&ps->csTsRead) ;
  483. +
  484.     //# USB endpoint
  485. -   WinUsb_ResetPipe(pusbep->fd, pusbep->endpoint & 0xFF);
  486. +   WinUsb_ResetPipe( pusbep->fd, pusbep->endpoint & 0xFF );
  487.     i = 0x01;
  488. -   WinUsb_SetPipePolicy(pusbep->fd, pusbep->endpoint & 0xFF, RAW_IO, sizeof(UCHAR), &i);
  489. -   WinUsb_SetPipePolicy(pusbep->fd, pusbep->endpoint & 0xFF, AUTO_CLEAR_STALL, sizeof(UCHAR), &i);
  490. +   WinUsb_SetPipePolicy( pusbep->fd, pusbep->endpoint & 0xFF, RAW_IO, sizeof( UCHAR ), &i );
  491. +   WinUsb_SetPipePolicy( pusbep->fd, pusbep->endpoint & 0xFF, AUTO_CLEAR_STALL, sizeof( UCHAR ), &i );
  492.  
  493. -#ifdef _DEBUG
  494. -   dwRet = sizeof(i);
  495. -   WinUsb_GetPipePolicy(ps->pUSB->fd, ps->pUSB->endpoint & 0xFF, MAXIMUM_TRANSFER_SIZE, &dwRet, &i);
  496. -   dmsg("MAX_TRANSFER_SIZE=%u", i);
  497. -#endif
  498. -
  499. -   ps->hThread = (HANDLE)_beginthreadex( NULL, 0, tsthread, ps, 0, NULL );
  500. -   if(INVALID_HANDLE_VALUE == ps->hThread) {
  501. -       warn_info(errno,"tsthread_create failed");
  502. -       uHeapFree(ps->buffer);
  503. +   #ifdef _DEBUG
  504. +
  505. +   dwRet = sizeof( i );
  506. +   WinUsb_GetPipePolicy( ps->pUSB->fd, ps->pUSB->endpoint & 0xFF, MAXIMUM_TRANSFER_SIZE, &dwRet, &i );
  507. +   dmsg( "MAX_TRANSFER_SIZE=%u", i );
  508. +   #endif
  509. +
  510. +   ps->hThread = ( HANDLE ) _beginthreadex( NULL, 0, tsthread, ps, 0, NULL );
  511. +   if ( INVALID_HANDLE_VALUE == ps->hThread ) {
  512. +       warn_info( errno, "tsthread_create failed" );
  513. +       uHeapFree( ps->buffer );
  514.         return -1;
  515. -   }else{
  516. -       SetThreadPriority( ps->hThread, THREAD_PRIORITY_TIME_CRITICAL );
  517. +   } else {
  518. +       SetThreadPriority( ps->hThread, THREAD_PRIORITY_HIGHEST );
  519.     }
  520.     *tptr = ps;
  521.     return 0;
  522. @@ -234,17 +396,24 @@
  523.  
  524.  void tsthread_destroy(const tsthread_ptr ptr)
  525.  {
  526. +   int i;
  527.     struct tsthread_param* const p = ptr;
  528.  
  529.     tsthread_stop(ptr);
  530.     p->flags |= 0x02;    //# canceled = T
  531. -   SetEvent(p->hTsEvent);
  532. -   if(WaitForSingleObject(p->hThread, 1000) != WAIT_OBJECT_0) {
  533. -       warn_msg(GetLastError(),"tsthread_destroy timeout");
  534. +   SetEvent(p->hTsRead);
  535. +   SetEvent(p->hTsAvailable);
  536. +   if (WaitForSingleObject(p->hThread, 1000) != WAIT_OBJECT_0) {
  537. +       warn_msg(GetLastError(), "tsthread_destroy timeout");
  538.         TerminateThread(p->hThread, 0);
  539.     }
  540. -   CloseHandle(p->hTsEvent);
  541. +   for (i = 0; i < TS_MaxNumIO; i++)
  542. +       CloseHandle(p->hTsEvents[i]);
  543. +   CloseHandle(p->hTsAvailable);
  544. +   CloseHandle(p->hTsRead);
  545. +   CloseHandle(p->hTsRestart);
  546.     CloseHandle(p->hThread);
  547. +   DeleteCriticalSection(&p->csTsRead);
  548.  
  549.     uHeapFree(p->buffer);
  550.  }
  551. @@ -254,10 +423,10 @@
  552.     struct tsthread_param* const p = ptr;
  553.     WinUsb_FlushPipe(p->pUSB->fd, p->pUSB->endpoint & 0xFF);
  554.     p->flags |= 0x01;    //# continue = T
  555. -   if(p->pUSB->startstopFunc)
  556. +   if (p->pUSB->startstopFunc)
  557.         p->pUSB->startstopFunc(p->pUSB->dev, 1);
  558.  
  559. -   SetEvent(p->hTsEvent);
  560. +   SetEvent(p->hTsAvailable);
  561.  }
  562.  
  563.  void tsthread_stop(const tsthread_ptr ptr)
  564. @@ -265,44 +434,58 @@
  565.     struct tsthread_param* const p = ptr;
  566.  
  567.     p->flags &= ~0x01U;    //# continue = F
  568. +
  569.     if(p->pUSB->startstopFunc)
  570.         p->pUSB->startstopFunc(p->pUSB->dev, 0);
  571.  
  572. +
  573.     if(!(p->pUSB->endpoint & 0x100) ) { //# Bulk
  574.         WinUsb_AbortPipe(p->pUSB->fd, p->pUSB->endpoint & 0xFF);
  575.     }
  576. +
  577. +   SetEvent(p->hTsRestart);
  578.  }
  579.  
  580.  int tsthread_read(const tsthread_ptr tptr, void ** const ptr)
  581.  {
  582.     struct tsthread_param* const ps = tptr;
  583.     int i, j;
  584. -   i = tsthread_readable(tptr);
  585. -   if(0 >= i) return 0;
  586.  
  587. -   j = ps->buff_pop;
  588. -   ps->actual_length[ps->buff_pop] = -1;
  589. -   if(ptr) {
  590. +   if(!ptr) {
  591. +       SetEvent(ps->hTsRestart) ;
  592. +       return 0 ;
  593. +   }
  594. +
  595. +   EnterCriticalSection(&ps->csTsRead) ;
  596. +   i = tsthread_readable(tptr);
  597. +   if(0 < i) {
  598. +       j = ps->buff_pop;
  599. +       ps->actual_length[ps->buff_pop] = -1;
  600.         *ptr = ps->buffer + (j * ps->buff_unitSize);
  601.         ps->buff_pop = (ps->buff_num - 1 > j) ? j + 1 : 0;
  602. -   }else{
  603. -       ps->actual_length[ps->buff_push] = -1;
  604. -       ps->buff_pop = ps->buff_push;
  605. +       SetEvent(ps->hTsRead) ;
  606.     }
  607. -   return i;
  608. +   LeaveCriticalSection(&ps->csTsRead) ;
  609. +
  610. +   return i<0 ? 0:i ;
  611.  }
  612.  
  613.  int tsthread_readable(const tsthread_ptr tptr)
  614.  {
  615.     struct tsthread_param* const ps = tptr;
  616. -   int j = ps->buff_pop;
  617. +   int j ;
  618. +
  619. +   if(!(ps->flags&0x01U)) return 0;
  620. +   if(WaitForSingleObject(ps->hTsRestart,0)==WAIT_OBJECT_0)
  621. +       return 0 ;
  622.  
  623. +   EnterCriticalSection(&ps->csTsRead) ;
  624. +   j= ps->buff_pop;
  625.     if(0 > j || ps->buff_num <= j) {  //# bug check
  626.         warn_info(j,"ts.buff_pop Out of range");
  627. -       ps->buff_pop = 0;
  628. -       return 0;
  629. +       j = -1;
  630.     }
  631. -   do {  //# skip empty blocks
  632. +   else do {  //# skip empty blocks
  633.         if(0 != ps->actual_length[j] ) break;
  634.         if(ps->buff_num -1 > j) {
  635.             j++;
  636. @@ -310,14 +493,17 @@
  637.             j = 0;
  638.         }
  639.     } while(j != ps->buff_pop);
  640. -   ps->buff_pop = j;
  641. -   return ps->actual_length[j];
  642. +   ps->buff_pop = j<0 ? 0 : j ;
  643. +   LeaveCriticalSection(&ps->csTsRead) ;
  644. +   return j<0 ? 0 : ps->actual_length[j];
  645.  }
  646.  
  647.  int tsthread_wait(const tsthread_ptr tptr, const int timeout)
  648.  {
  649.     struct tsthread_param* const ps = tptr;
  650. -   DWORD dRet = WaitForSingleObject( ps->hTsEvent , timeout );
  651. +   DWORD dRet ;
  652. +   if(tsthread_readable(tptr)>0) return 1 ; //# already available
  653. +   dRet = WaitForSingleObject( ps->hTsAvailable , timeout );
  654.     if(WAIT_OBJECT_0 == dRet)  return 1;
  655.     else if(WAIT_TIMEOUT == dRet)  return 0;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement