Advertisement
Guest User

BonD_FSUSB2i-20160219_mod_20180227.diff

a guest
Feb 26th, 2018
228
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Diff 19.14 KB | None | 0 0
  1. diff -uPr BonD_FSUSB2i-20160219_org2/src/tsthread.c BonD_FSUSB2i-20160219_mod2/src/tsthread.c
  2. --- BonD_FSUSB2i-20160219_org2/src/tsthread.c   2016-02-18 20:21:28.000000000 +0900
  3. +++ BonD_FSUSB2i-20160219_mod2/src/tsthread.c   2018-02-27 10:26:31.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,360 @@
  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(!isTimeout&&last_state>0) {
  296. +                           HANDLE events[3];
  297. +                           events[0]=ps->hTsRead;
  298. +                           events[1]=ps->hTsRestart ;
  299. +                           events[2]=ps->hTsEvents[ri+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 (!(ps->flags & 0x01)) break;
  312. +                   if (ps->pUSB->endpoint & 0x100) { //# Isochronous
  313. +                       //tsthread_stop(ps);
  314. +                       break;
  315. +                   }
  316. +                   if(ps->actual_length[ps->buff_push]>0||ps->actual_length[ps->buff_push]==-2)
  317. +                       break ; //# buffer busy
  318. +                   else {
  319. +                       buffer = ps->buffer + (ps->buff_push * ps->buff_unitSize) ;
  320. +                       last_state =  ps->actual_length[ps->buff_push] ;
  321. +                       ps->actual_length[ps->buff_push] = -2;
  322. +                   }
  323. +                   pContext->index = ps->buff_push;
  324. +                   pContext->bytesRead = 0 ;
  325. +                   ZeroMemory(&pContext->ol,sizeof(OVERLAPPED));
  326. +                   pContext->ol.hEvent = ps->hTsEvents[si];
  327. +                   lnTransfered = 0;
  328. +                   ResetEvent(pContext->ol.hEvent);
  329. +                   bRet = WinUsb_ReadPipe(ps->pUSB->fd, ps->pUSB->endpoint & 0xFF,
  330. +                       buffer, ps->buff_unitSize, &lnTransfered, &(pContext->ol));
  331. +                   dRet = GetLastError();
  332. +                   if (FALSE == bRet && ERROR_IO_PENDING != dRet) {
  333. +                       warn_info(dRet, "submitURB failed");
  334. +                       ps->actual_length[ps->buff_push] = last_state;
  335. +                       ResetEvent(ps->hTsEvents[si]);
  336. +                       pContext->index = -1;
  337. +                   }else {
  338. +                       if(ps->buff_push+1>=ps->buff_num)
  339. +                           ps->buff_push=0;
  340. +                       else
  341. +                           ps->buff_push++;
  342. +                       if(bRet) pContext->bytesRead = lnTransfered ;
  343. +                       ps->total_submit++;
  344. +                       dRet = 0;
  345. +                   }
  346. +                   if(bRet) SetEvent(ps->hTsEvents[si]) ;
  347. +                   if(dRet) break ;
  348. +                   dRet = 0;bRet = FALSE;
  349. +                   if (++si >= TS_MaxNumIO) si=0;
  350. +               }
  351. +               //if(dRet) break ;
  352. +           }
  353. +
  354. +       }
  355. +
  356. +       if(isTimeout) continue ;
  357. +       if(++ri >= TS_MaxNumIO) ri=0 ;
  358. +
  359.     }
  360.  
  361. -   return countURB;
  362. +   //# dispose
  363. +   tsthread_purgeURB(ps);
  364. +
  365. +   return dRet ;
  366.  }
  367.  
  368.  /* TS thread function issues URB requests. */
  369.  static unsigned int __stdcall tsthread(void* const param)
  370.  {
  371.     struct tsthread_param* const ps = param;
  372. +   unsigned int result = 0;
  373. +
  374.     ps->buff_push = 0;
  375.  
  376. -   for(;;) {
  377. -       DWORD dRet;
  378. -       if(ps->flags & 0x01) {
  379. -           //# continue to issue a new URB request
  380. -           submitURB(ps);
  381. -       }
  382. -       if(ps->flags & 0x02) {
  383. -           //# canceled
  384. -           reapURB(ps);
  385. -           break;
  386. -       }
  387. +   result = tsthread_bulkURB(ps);
  388.  
  389. -       dRet = WaitForSingleObject( ps->hTsEvent , TS_PollTimeout );
  390. -       if(WAIT_OBJECT_0 == dRet || WAIT_TIMEOUT == dRet) {
  391. -           if(reapURB(ps) < 0) break;
  392. -           //# timeout
  393. -           if(WAIT_TIMEOUT == dRet && ps->flags & 0x01) {
  394. -               dmsg("poll timeout");
  395. -           }
  396. -       }else{
  397. -           dRet = GetLastError();
  398. -           warn_info(dRet,"poll failed");
  399. -           break;
  400. -       }
  401. -   }
  402.     _endthreadex( 0 );
  403. -   return 0;
  404. +   return result ;
  405.  }
  406.  
  407.  /* public function */
  408.  
  409. -int tsthread_create(tsthread_ptr* const tptr, const struct usb_endpoint_st* const pusbep)
  410. +int tsthread_create( tsthread_ptr* const tptr,
  411. +                    const struct usb_endpoint_st* const pusbep
  412. +                  )
  413.  {
  414.     struct tsthread_param* ps;
  415.     DWORD dwRet, i;
  416.  
  417. -   {//#
  418. -       const unsigned param_size  = ROUNDUP(sizeof(struct tsthread_param), 0xF);
  419. -       const unsigned buffer_size = ROUNDUP(TS_BufSize ,0xF);
  420. -       const unsigned unitSize = ROUNDUP(pusbep->xfer_size ,0x1FF);
  421. +   { //#
  422. +       const unsigned param_size = ROUNDUP( sizeof( struct tsthread_param ), 0xF );
  423. +       const unsigned buffer_size = ROUNDUP( TS_BufSize , 0xF );
  424. +       const unsigned unitSize = ROUNDUP( pusbep->xfer_size, 0x1FF ) ;
  425.         const unsigned unitNum = TS_BufSize / unitSize;
  426. -       const unsigned actlen_size = sizeof(int) * unitNum;
  427. +       const unsigned actlen_size = sizeof( int ) * unitNum;
  428.         char *ptr, *buffer_ptr;
  429. -       unsigned totalSize = param_size + actlen_size + buffer_size;
  430. +       unsigned totalSize = param_size + actlen_size + buffer_size ;
  431.         ptr = uHeapAlloc( totalSize );
  432. -       if(NULL == ptr) {
  433. +       if ( NULL == ptr ) {
  434.             dwRet = GetLastError();
  435. -           warn_msg(dwRet,"failed to allocate TS buffer");
  436. +           warn_msg( dwRet, "failed to allocate TS buffer" );
  437.             return -1;
  438.         }
  439.         buffer_ptr = ptr;
  440.         ptr += buffer_size;
  441. -       ps = (struct tsthread_param*) ptr;
  442. +       ps = ( struct tsthread_param* ) ptr;
  443.         ps->buffer = buffer_ptr;
  444.         ptr += param_size;
  445. -       ps->actual_length = (int*)ptr;
  446. +       ps->actual_length = ( int* ) ptr;
  447.         //ptr += actlen_size;
  448.         ps->buff_unitSize = unitSize;
  449.         ps->buff_num = unitNum;
  450. -       ps->actual_length[0] = -1;   //# the first block is not-used
  451. -
  452. +       if ( actlen_size ) {
  453. +           for ( i = 0;i < unitNum;i++ )
  454. +               ps->actual_length[ i ] = -1;   //# rest all values to empty
  455. +       }
  456.     }
  457.     ps->pUSB = pusbep;
  458.     ps->flags = 0;
  459.     ps->buff_pop = 0;
  460. -  
  461. -   for(i = 0; i < TS_MaxNumIO; i++) {
  462. -       ps->ioContext[i].index = -1;    //# mark it unused
  463. +   ps->total_submit = 0;
  464. +
  465. +   for ( i = 0; i < TS_MaxNumIO; i++ ) {
  466. +       ps->ioContext[ i ].index = -1;    //# mark it unused
  467. +       ps->hTsEvents[ i ] = CreateEvent( NULL, TRUE, FALSE, NULL );
  468. +       ZeroMemory( &ps->ioContext[ i ].ol, sizeof( OVERLAPPED ) );
  469. +       ps->ioContext[ i ].ol.hEvent = ps->hTsEvents[ i ];
  470.     }
  471. -   ps->hTsEvent = CreateEvent ( NULL, FALSE, TRUE, NULL );
  472. +
  473. +   //# it arranges for event handles to look like circular buffer
  474. +   for ( i = 0; i < TS_MaxNumIO - 1; i++ ) {
  475. +       ps->hTsEvents[ i + TS_MaxNumIO ] = ps->hTsEvents[ i ];
  476. +   }
  477. +   ps->hTsAvailable = CreateEvent( NULL, FALSE, FALSE, NULL );
  478. +   ps->hTsRead = CreateEvent( NULL, FALSE, FALSE, NULL );
  479. +   ps->hTsRestart = CreateEvent( NULL, TRUE, FALSE, NULL );
  480. +   InitializeCriticalSection(&ps->csTsRead) ;
  481. +
  482.     //# USB endpoint
  483. -   WinUsb_ResetPipe(pusbep->fd, pusbep->endpoint & 0xFF);
  484. +   WinUsb_ResetPipe( pusbep->fd, pusbep->endpoint & 0xFF );
  485.     i = 0x01;
  486. -   WinUsb_SetPipePolicy(pusbep->fd, pusbep->endpoint & 0xFF, RAW_IO, sizeof(UCHAR), &i);
  487. -   WinUsb_SetPipePolicy(pusbep->fd, pusbep->endpoint & 0xFF, AUTO_CLEAR_STALL, sizeof(UCHAR), &i);
  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.  
  491. -#ifdef _DEBUG
  492. -   dwRet = sizeof(i);
  493. -   WinUsb_GetPipePolicy(ps->pUSB->fd, ps->pUSB->endpoint & 0xFF, MAXIMUM_TRANSFER_SIZE, &dwRet, &i);
  494. -   dmsg("MAX_TRANSFER_SIZE=%u", i);
  495. -#endif
  496. -
  497. -   ps->hThread = (HANDLE)_beginthreadex( NULL, 0, tsthread, ps, 0, NULL );
  498. -   if(INVALID_HANDLE_VALUE == ps->hThread) {
  499. -       warn_info(errno,"tsthread_create failed");
  500. -       uHeapFree(ps->buffer);
  501. +   #ifdef _DEBUG
  502. +
  503. +   dwRet = sizeof( i );
  504. +   WinUsb_GetPipePolicy( ps->pUSB->fd, ps->pUSB->endpoint & 0xFF, MAXIMUM_TRANSFER_SIZE, &dwRet, &i );
  505. +   dmsg( "MAX_TRANSFER_SIZE=%u", i );
  506. +   #endif
  507. +
  508. +   ps->hThread = ( HANDLE ) _beginthreadex( NULL, 0, tsthread, ps, 0, NULL );
  509. +   if ( INVALID_HANDLE_VALUE == ps->hThread ) {
  510. +       warn_info( errno, "tsthread_create failed" );
  511. +       uHeapFree( ps->buffer );
  512.         return -1;
  513. -   }else{
  514. -       SetThreadPriority( ps->hThread, THREAD_PRIORITY_TIME_CRITICAL );
  515. +   } else {
  516. +       SetThreadPriority( ps->hThread, THREAD_PRIORITY_HIGHEST );
  517.     }
  518.     *tptr = ps;
  519.     return 0;
  520. @@ -234,17 +394,24 @@
  521.  
  522.  void tsthread_destroy(const tsthread_ptr ptr)
  523.  {
  524. +   int i;
  525.     struct tsthread_param* const p = ptr;
  526.  
  527.     tsthread_stop(ptr);
  528.     p->flags |= 0x02;    //# canceled = T
  529. -   SetEvent(p->hTsEvent);
  530. -   if(WaitForSingleObject(p->hThread, 1000) != WAIT_OBJECT_0) {
  531. -       warn_msg(GetLastError(),"tsthread_destroy timeout");
  532. +   SetEvent(p->hTsRead);
  533. +   SetEvent(p->hTsAvailable);
  534. +   if (WaitForSingleObject(p->hThread, 1000) != WAIT_OBJECT_0) {
  535. +       warn_msg(GetLastError(), "tsthread_destroy timeout");
  536.         TerminateThread(p->hThread, 0);
  537.     }
  538. -   CloseHandle(p->hTsEvent);
  539. +   for (i = 0; i < TS_MaxNumIO; i++)
  540. +       CloseHandle(p->hTsEvents[i]);
  541. +   CloseHandle(p->hTsAvailable);
  542. +   CloseHandle(p->hTsRead);
  543. +   CloseHandle(p->hTsRestart);
  544.     CloseHandle(p->hThread);
  545. +   DeleteCriticalSection(&p->csTsRead);
  546.  
  547.     uHeapFree(p->buffer);
  548.  }
  549. @@ -254,10 +421,10 @@
  550.     struct tsthread_param* const p = ptr;
  551.     WinUsb_FlushPipe(p->pUSB->fd, p->pUSB->endpoint & 0xFF);
  552.     p->flags |= 0x01;    //# continue = T
  553. -   if(p->pUSB->startstopFunc)
  554. +   if (p->pUSB->startstopFunc)
  555.         p->pUSB->startstopFunc(p->pUSB->dev, 1);
  556.  
  557. -   SetEvent(p->hTsEvent);
  558. +   SetEvent(p->hTsAvailable);
  559.  }
  560.  
  561.  void tsthread_stop(const tsthread_ptr ptr)
  562. @@ -265,44 +432,58 @@
  563.     struct tsthread_param* const p = ptr;
  564.  
  565.     p->flags &= ~0x01U;    //# continue = F
  566. +
  567.     if(p->pUSB->startstopFunc)
  568.         p->pUSB->startstopFunc(p->pUSB->dev, 0);
  569.  
  570. +
  571.     if(!(p->pUSB->endpoint & 0x100) ) { //# Bulk
  572.         WinUsb_AbortPipe(p->pUSB->fd, p->pUSB->endpoint & 0xFF);
  573.     }
  574. +
  575. +   SetEvent(p->hTsRestart);
  576.  }
  577.  
  578.  int tsthread_read(const tsthread_ptr tptr, void ** const ptr)
  579.  {
  580.     struct tsthread_param* const ps = tptr;
  581.     int i, j;
  582. -   i = tsthread_readable(tptr);
  583. -   if(0 >= i) return 0;
  584.  
  585. -   j = ps->buff_pop;
  586. -   ps->actual_length[ps->buff_pop] = -1;
  587. -   if(ptr) {
  588. +   if(!ptr) {
  589. +       SetEvent(ps->hTsRestart) ;
  590. +       return 0 ;
  591. +   }
  592. +
  593. +   EnterCriticalSection(&ps->csTsRead) ;
  594. +   i = tsthread_readable(tptr);
  595. +   if(0 < i) {
  596. +       j = ps->buff_pop;
  597. +       ps->actual_length[ps->buff_pop] = -1;
  598.         *ptr = ps->buffer + (j * ps->buff_unitSize);
  599.         ps->buff_pop = (ps->buff_num - 1 > j) ? j + 1 : 0;
  600. -   }else{
  601. -       ps->actual_length[ps->buff_push] = -1;
  602. -       ps->buff_pop = ps->buff_push;
  603. +       SetEvent(ps->hTsRead) ;
  604.     }
  605. -   return i;
  606. +   LeaveCriticalSection(&ps->csTsRead) ;
  607. +
  608. +   return i<0 ? 0:i ;
  609.  }
  610.  
  611.  int tsthread_readable(const tsthread_ptr tptr)
  612.  {
  613.     struct tsthread_param* const ps = tptr;
  614. -   int j = ps->buff_pop;
  615. +   int j ;
  616. +
  617. +   if(!(ps->flags&0x01U)) return 0;
  618. +   if(WaitForSingleObject(ps->hTsRestart,0)==WAIT_OBJECT_0)
  619. +       return 0 ;
  620.  
  621. +   EnterCriticalSection(&ps->csTsRead) ;
  622. +   j= ps->buff_pop;
  623.     if(0 > j || ps->buff_num <= j) {  //# bug check
  624.         warn_info(j,"ts.buff_pop Out of range");
  625. -       ps->buff_pop = 0;
  626. -       return 0;
  627. +       j = -1;
  628.     }
  629. -   do {  //# skip empty blocks
  630. +   else do {  //# skip empty blocks
  631.         if(0 != ps->actual_length[j] ) break;
  632.         if(ps->buff_num -1 > j) {
  633.             j++;
  634. @@ -310,14 +491,17 @@
  635.             j = 0;
  636.         }
  637.     } while(j != ps->buff_pop);
  638. -   ps->buff_pop = j;
  639. -   return ps->actual_length[j];
  640. +   ps->buff_pop = j<0 ? 0 : j ;
  641. +   LeaveCriticalSection(&ps->csTsRead) ;
  642. +   return j<0 ? 0 : ps->actual_length[j];
  643.  }
  644.  
  645.  int tsthread_wait(const tsthread_ptr tptr, const int timeout)
  646.  {
  647.     struct tsthread_param* const ps = tptr;
  648. -   DWORD dRet = WaitForSingleObject( ps->hTsEvent , timeout );
  649. +   DWORD dRet ;
  650. +   if(tsthread_readable(tptr)>0) return 1 ; //# already available
  651. +   dRet = WaitForSingleObject( ps->hTsAvailable , timeout );
  652.     if(WAIT_OBJECT_0 == dRet)  return 1;
  653.     else if(WAIT_TIMEOUT == dRet)  return 0;
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement