Advertisement
Guest User

BonD_uSUNpTV-20160219_mod_20180228.diff

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