From 35d9a8214252dbe79aeb69ae47d2e5c58a654702 Mon Sep 17 00:00:00 2001 From: Keith Packard Date: Mon, 30 Aug 2010 05:27:45 -0700 Subject: [PATCH 1/1] libaltos: Use overlapped I/O on windows Otherwise, reads block writes and vice-versa. Crazy stuff. Signed-off-by: Keith Packard --- ao-tools/libaltos/altos.dll | Bin 30550 -> 31765 bytes ao-tools/libaltos/libaltos.c | 127 +++++++++++++++++++++++++---------- 2 files changed, 90 insertions(+), 37 deletions(-) diff --git a/ao-tools/libaltos/altos.dll b/ao-tools/libaltos/altos.dll index f40181e825f190b971dcea66e869405e043e9b80..28e9b4ad0ef365d7bda81e310fd5b2afdcdb6d94 100755 GIT binary patch delta 9549 zcmb_h4_H)Xx z-tYXr-}`>=_kMroJI6m==YKKGw>3wvIP`Qbm%?#p1&-_I0t_L%kiw1OIL^B3m1N=L zA9h{3UkLKwb#E*)@`b_1NVMo6W7u~7fyvRRjVdB6^Kc1<(Yp#i6<=Ma(XGkS@@9n#@pV8-3xZqag_bF(q1ccxLpqseJC z4r~Y3Fc{j@Q{ORg`?kwv?zwgd@^b6%$avtSh_1L$Q~_>pTk8CB)mLLN-Zr`5xtn;a zPE*Ti_Okz2;fTn({Szm@v!S@UVNmDvYZ!Lb8wb9DBPaSr+!`AK%A@BP<3OOuv;k|P z&PePi=UHNhgJdL9S2)`qkU9RzV2UxSsmC6JmL=5kShyVivS2n4FjI&NXNiHa0vFB} zK=tcbbzq!u>@L<8I5WQHF3H+?nuc2-J!qOfvr{LHw_`1pVaV`5MD9+I( zu{AW(TVWj6vTEc5O4Z_qL1W9Rpc9n4hLeX$)z`E(v_Zp(t~GlYDire+WCPSXBZpkK z_&GJkfv2Sj(<9FD0~=94;X+CK6055|vA2O-(bQfWFV!8WVgeg>NE-daaYHj6q@JDU zN5!K@JT2LwqeId*ZU+@T`FB$%QVb34fGCbZ45wi*2$K?a0_(<=CQuFvubB}wtrw04 z;lKzy!%_y&AsOnVxMBUkwLqzQEnbeEO#klzOCytFencAA=A>RpD_*9MMxp#SBTDBf zj3ykzq_Gev(6~-H&o`XW7qGuzNHLZU3G_mb19_6Y&bh4}PyZV^-c6=l z^fs+^xg3-mS8r35q^VYe8d`0=O?J5k;wGimN+$Ax3!of*gix{Adb68jVA7i1ETvCs zIx06IeK9Q(@N)^!&H*RYsS zqtHLXvO*Jtw?|k-Xew`DM?y^#uzQzb`|4WiX}g^4&n&Kf*q{E|BOB8CGduqgx|rv; zuz6vz{8&~QW(hC+&gJ^xR1gP43}N8W@7Qm`?h!J-V|`%>j)PKTjMCVWt)tPF4wHpW z2BVy-hMn~zzsI<-eWmt4-9m0|w5%F#sUL9;t~#Yxo9`bPWsV>vo8PEF?eDXrD21^~ z>v5^|4nO;TVB59P#!r+sS3(pHv$i%@LX4!P@lbRv<{6IfNzGE;qOW@iQmC? zin%j&3Fzuam;FH;_7SbtU($1Vn`=zNbxp%HzW#eGY*QS(?EA*$YB-}Scx=__)+adg zXV(Ph>DC#1i@r&hz+xln_!PD~B4x4;VVw8}BJQ@K=3HV7q67{^;NXQPJFt^~N9)@* z_HD$Baf67j^_jiB*#|OFdb8U}IkUSD4rQ^0di~OyXz$JLkQenf4L%C0BAIjY}Z6>bV^H!zjMsLr}txY+!Q#I({ zh-IODYp7vRgNe&Bf7XU8Cs3iawy|ql#`< z^j<}8R&=wXI~2W1(QS&ZlC>jYj{@W>dXl136`il>DT+2Jx>(UO6Z^@|E|+p=3P8SGTmq{eyPLHO%Z0dvP9f@w(CLcy=jZg}?tqIY_aii27_~T9 zG|*F^>7JMmP4~na=s@T_&~#iA4_6zm6B>%^?3^F-7SC*aoUq~$3y6((gyZBS@mFL# zG>K`PEJkROo6)j_qE5mo5(P~%fOeA0iuAz;$!fHb>{KKNnq;Xg4lWfHk`$0hwBu#D zf;x#2&m@ykCvhsW4w_`PA}>Lc+)!i)K1tqH#C{LQ?Zfr(1TO9SQ4c|&ZQ=MKybYO% zYv;>oY#YmQC-3Q;KH<}_ER!80+kl+XC0r?6ff<2yjlwPhTMLXMQOYo|t_{2H9pg9$ z^petY9r_j|s1}|f6CoBz7Gx1*HDnW{5wZtz1kw%ZgItAB`5Jl{BGh3XAbLm)WFo`_ zNr7ZRav{s=I0sjZN+qNgvKg`s(gvY&0Qw!s1;`*ohp?&q{{>wtJNy@;{uhI0#~#Yk z+PE3DWhM5q>?g{q?U@|==An6!#r*6td)^aewN)iGHD#rX%IfN??CfFF!pQsm9xbV` z&stx*xT5;;s{BBEVXPo6(UV{sK4fD4?;&^)cv(uf^v(o0K6{I=R zD$<`%Ka&3I^se+%=^v(FNWYr?*YvQA$c#A|OEQWw8Zy4h;Nmd(825P7G}BB|zNymm zl&RI!Vd^toFx@cSYhGzCHE%LMXFg^=YyPwOJ9CI7+7fTM-(s<(TIN_>mut)>uPJIwbuHS^*QTy>u&2l>nqmRtZ!ORSWj6$w0>&6Wc}Rw zwe^PemQ_EMGhsc^WI@yWD0UI|g?Z3?(;PNp)>uL-n}nj<0np$c$CwR3YU+UQ!_p zNS_LMAIKFIavjJG6%vcpsKqOnxBFZmdZPz&uPrQ$j~}TN`Z+c|HJ-0z3o{H8VI_U0 z@#D(vYwN3jhW+nB+;+CRch8Dv?P;@_HZ38+Ymrz%AA*ciM_H6tRFz=?ZG-P|?6LeH z!EKwfJJTRc?PGkVfgfh(bc4T*;$yDmW?_j%@iDBAlf&3e6PUeJw z%}8GU-L!=gcA(m>q!G&yaSd@i3U&EM^m|A=FF&Q94~|Ja3xm{ z02$IrXGb2YT(}&fJn&K=GXY`~DM!slAoK(u3i2F~B`VI(fncqU;_L%bs^T02LMNZs z^Lvv4=~ZTb1k$bqByjG9iD+xGD}_OUUCxddbo$-1D)E;U&#|&8D@Ar}w#X85Mg7+Z z5xWLax(%Zw5?-!;F~`6rE)ex5j8aXBlPO1;cAkNy=ZN}=K9or^rHhS)7t1_RpXEa_ z$&|g!nQLIjK@of?DKh08Gp{gA9732%9P;K$-t1#wlMT+W$pr?MJXh3L`cQIY%6azS zN(0L+5cS)9DETs_kNp~y`{#@LS|7@Ci4xI+nNh_wbuXJd$Dl9vF({UO9%ilu2G)Vh z$M{gz%9I0aT#kYDV1j1O69ol4&UVc;u=qStpW z0}D+z@)y~-g$BZDVYkf{`CRthQiHzHXIZz)lpXW%!MZ?XV-|_}TRwdsl}W+^kv+9U zWWh_ZZhbr*mq}yhAPe~+?A=*`tQo{TKE!UBcmSz-Zjs2u#iBmQhtwmJVnG^4mpO%^ zKFWvGCz1HgtO*%Dj6HePhjL!_6Nd3Uu~cMx7mE7TKBSAXpG_nCs) z+p<_>JC=xgy1}To`+)5FHnMUPuERiDb|*1tcFT2Ahtg&{}7;BJT0E>T%O~v$N%c^Ogkfr73BxATg#KD4f^crcf5hgXOA`L zP9*sP`>&O=Q*Qd$p1G50)!m6C>olymAfAP;FisotanN%o-5Po)k~~PAM-2GbcC+_a z{4C-NAH0iYtTgZkU}e}{Xk^hjBHOl5WP28gf<-_qvsiPk$VRXxJ}eN0i89oP$xSX4 z+1WzTaorOF^2)i8-C_JJdGA>wZuIoOVECuJ3z&gSQmn8DP-X$4LQgWX6i5ushlCWB z*Ot+hDN5zJ6r3e=U#FEKa7A_Y+BGG1E=5Ip1|;{S$*vCov3aau%DoAs5gN%+y8m|| z%T=5&fVhk7=UX5q9#?3&duqH3uL&2G6w9RXK-|+NBlMbL^|&r7DyyxnUeB3SK^KCv z$-^Pf6+o!a$8*`wvxMkyh4w=G0ClU(PDo~Pqc|6U&^WzTLlTFayIl)-C!pfxgaMhU z@;pW1VEk^gbU?$Z(JxU*UQQ{H0nb>AYU=IyF2UJ62r=#845^SNAa+&vyMPoELjB7L z`4u3Os{4~bsCdV5K|v@3veoB6)XS6Jf2OE9i=pcouAW{$Rv=Ll2mLGa3aDQd^)ete zDo3T{NGY<_6F|CER?jOOZ)dLpai1Ns)mb3tWvd{i`>QOx*xiiBm2a%A zu$OUbRbA4H(IkZBUC8l3kl<=>5N1MDIhZYR+*v7FSGI1AqvlC&tIG8{ki6+7QeByy zYg2Jrz&WZy_5(4ZKN_t(;-f(J;K@62Zv)YdIw8ud>gyb9xj2<0`p>%yDzpCpQmD$% z5D<5fJLB;3a$Myn0!Y5fY6=i{k*(6huo=A(QR94&dQ^^9DQ4bO*8)lLxGq{#QdPBn z4OgtPaw=Bd={N)=6+L+UbOUi*RGEDO$bGMpWBeRQo2N4haR>002)C`5R>wLXL$ylPxDJTU6D?lvq+w6;AQanE;Eehapz|FI zEJwv@24|1Qb5UL0nv&{rE?>oY!2uGjUT?UsO9-Lv752V_j9&5|1EF6nuhnHBxt`9* z_6CrxDug!4Q56!V!y&QR0~M95USDg+0k4WN24*oH4!NENut!_rB2zTD!-vsHmi_uB_JHtm5nk zNBXqFxkvk&kMom2yeAihdj-f=%!YT*eM?rE)P^GG-%rG$uj=e>Acs8x5px`nW)Cu1 zWM7mW9=D;stiG%W-?&S;qLM26`nsZx_=GJ1om?t0^k_i4Wd3b22+ub6GF7 vkN!wb4Zqq@sJ#<&ZO9z+PyD3U4o6FVe&X}FErli3eHi(ZEuBBs75M!RQ`e|0 delta 8550 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 QHe98P8wdN|Y^e(RKjFTGSO5S3 diff --git a/ao-tools/libaltos/libaltos.c b/ao-tools/libaltos/libaltos.c index 1d3b26dd..059d2ae9 100644 --- a/ao-tools/libaltos/libaltos.c +++ b/ao-tools/libaltos/libaltos.c @@ -492,7 +492,7 @@ struct altos_file { int in_read; }; -struct altos_file * +PUBLIC struct altos_file * altos_open(struct altos_device *device) { struct altos_file *file = calloc (sizeof (struct altos_file), 1); @@ -550,7 +550,7 @@ altos_open(struct altos_device *device) return file; } -void +PUBLIC void altos_close(struct altos_file *file) { if (file->fd != -1) { @@ -566,14 +566,14 @@ altos_close(struct altos_file *file) } } -void +PUBLIC void altos_free(struct altos_file *file) { altos_close(file); free(file); } -int +PUBLIC int altos_flush(struct altos_file *file) { while (file->out_used) { @@ -597,7 +597,7 @@ altos_flush(struct altos_file *file) return 0; } -int +PUBLIC int altos_putchar(struct altos_file *file, char c) { int ret; @@ -619,7 +619,7 @@ altos_putchar(struct altos_file *file, char c) #include #endif -int +static int altos_fill(struct altos_file *file, int timeout) { int ret; @@ -663,7 +663,7 @@ altos_fill(struct altos_file *file, int timeout) return 0; } -int +PUBLIC int altos_getchar(struct altos_file *file, int timeout) { int ret; @@ -699,6 +699,9 @@ struct altos_file { unsigned char in_data[USB_BUF_SIZE]; int in_used; int in_read; + OVERLAPPED ov_read; + BOOL pend_read; + OVERLAPPED ov_write; }; PUBLIC struct altos_list * @@ -817,42 +820,72 @@ altos_list_finish(struct altos_list *list) } static int -altos_fill(struct altos_file *file, int timeout) +altos_queue_read(struct altos_file *file) { - DWORD result; DWORD got; - COMMTIMEOUTS timeouts; - - if (file->in_read < file->in_used) + if (file->pend_read) return LIBALTOS_SUCCESS; - file->in_read = file->in_used = 0; - if (timeout) - timeouts.ReadTotalTimeoutConstant = timeout; - else - timeouts.ReadTotalTimeoutConstant = 1000; + if (!ReadFile(file->handle, file->in_data, USB_BUF_SIZE, &got, &file->ov_read)) { + if (GetLastError() != ERROR_IO_PENDING) + return LIBALTOS_ERROR; + file->pend_read = TRUE; + } else { + file->pend_read = FALSE; + file->in_read = 0; + file->in_used = got; + } + return LIBALTOS_SUCCESS; +} - timeouts.ReadIntervalTimeout = MAXDWORD; - timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; - timeouts.WriteTotalTimeoutMultiplier = 0; - timeouts.WriteTotalTimeoutConstant = 0; +static int +altos_wait_read(struct altos_file *file, int timeout) +{ + DWORD ret; + DWORD got; - if (!SetCommTimeouts(file->handle, &timeouts)) - printf("SetCommTimeouts failed %d\n", GetLastError()); + if (!file->pend_read) + return LIBALTOS_SUCCESS; - for (;;) { - if (!ReadFile(file->handle, file->in_data, USB_BUF_SIZE, &got, NULL)) { - result = GetLastError(); + if (!timeout) + timeout = INFINITE; + + ret = WaitForSingleObject(file->ov_read.hEvent, timeout); + switch (ret) { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(file->handle, &file->ov_read, &got, FALSE)) return LIBALTOS_ERROR; - got = 0; - } + file->pend_read = FALSE; file->in_read = 0; file->in_used = got; - if (got) - return LIBALTOS_SUCCESS; - if (timeout) - return LIBALTOS_TIMEOUT; + break; + case WAIT_TIMEOUT: + return LIBALTOS_TIMEOUT; + break; + default: + return LIBALTOS_ERROR; } + return LIBALTOS_SUCCESS; +} + +static int +altos_fill(struct altos_file *file, int timeout) +{ + int ret; + + if (file->in_read < file->in_used) + return LIBALTOS_SUCCESS; + + file->in_read = file->in_used = 0; + + ret = altos_queue_read(file); + if (ret) + return ret; + ret = altos_wait_read(file, timeout); + if (ret) + return ret; + + return LIBALTOS_SUCCESS; } PUBLIC int @@ -861,12 +894,21 @@ altos_flush(struct altos_file *file) DWORD put; char *data = file->out_data; char used = file->out_used; - DWORD result; + DWORD ret; while (used) { - if (!WriteFile(file->handle, data, used, &put, NULL)) { - result = GetLastError(); - return LIBALTOS_ERROR; + if (!WriteFile(file->handle, data, used, &put, &file->ov_write)) { + if (GetLastError() != ERROR_IO_PENDING) + return LIBALTOS_ERROR; + ret = WaitForSingleObject(file->ov_write.hEvent, INFINITE); + switch (ret) { + case WAIT_OBJECT_0: + if (!GetOverlappedResult(file->handle, &file->ov_write, &put, FALSE)) + return LIBALTOS_ERROR; + break; + default: + return LIBALTOS_ERROR; + } } data += put; used -= put; @@ -881,6 +923,7 @@ altos_open(struct altos_device *device) struct altos_file *file = calloc (1, sizeof (struct altos_file)); char full_name[64]; DCB dcbSerialParams = {0}; + COMMTIMEOUTS timeouts; if (!file) return NULL; @@ -889,11 +932,21 @@ altos_open(struct altos_device *device) strcat(full_name, device->path); file->handle = CreateFile(full_name, GENERIC_READ|GENERIC_WRITE, 0, NULL, OPEN_EXISTING, - FILE_ATTRIBUTE_NORMAL, NULL); + FILE_FLAG_OVERLAPPED, NULL); if (file->handle == INVALID_HANDLE_VALUE) { free(file); return NULL; } + file->ov_read.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + file->ov_write.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL); + + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; + timeouts.ReadTotalTimeoutConstant = 1 << 30; /* almost forever */ + timeouts.WriteTotalTimeoutMultiplier = 0; + timeouts.WriteTotalTimeoutConstant = 0; + SetCommTimeouts(file->handle, &timeouts); + dcbSerialParams.DCBlength = sizeof(dcbSerialParams); if (!GetCommState(file->handle, &dcbSerialParams)) { CloseHandle(file->handle); -- 2.30.2