The XMODEM/YMODEM attached device driver attaches to an existing serial device and (after converting the channel to 8-bits with only hardware handshaking - XMODEM is an 8-bit protocol) allows serial reads and writes to be converted into XMODEM/YMODEM packets.
The P_FCANCEL service which you would normally use during asynchronous operations (for instance when a timeout event is detected you will call P_FCANCEL on any outstanding serial event) will cause a panic when called on an outstanding P_READ/P_WRITE when XMD: has already been attached to a TTY: channel. The proper service to call is P_FDISCONNECT.
These two preprocessor macros are defined differently, and if you are using a standardized read-with-timeout or write-with-timeout style utility routine, it needs to have a state variable or flag to indicate whether it should call the P_FCANCEL or the P_FDISCONNECT service. (In the case of active objects, this is extremely important - since active objects will use the P_FCANCEL service of their own volition - you may have to replace several methods.)
If you're dealing with multiple permanent graphics contexts, when destroying a window which has an associated permanent graphics context or freeing an existing permanent graphics context, it is important to call gSetGC0(gc) where gc is the graphics context id of the permanent graphics context which you expect to be drawing to.
When a permanent graphics context is destroyed while it is the current graphics context, the Window Server is left in un-defined state with regards to the current graphics context. Any subsequent drawing not preceded by a gSetGC0(gc) could result in a panic. With client-side buffering, it may not be immediately obvious, either!
While Psion currently claims that there is no way to find out the current graphics context id, there is one way to avoid this problem - minimize the live time of graphics contexts. If you are sufficiently adept at minimizing and localizing all drawing, you can also get away with using temporary graphics contexts - which do restore the previous permanent graphics context upon the call to gFreeTempGC(). One caveat: You can only have one temporary gc at any given time - and you cannot use any permanent graphics contexts during the live time of the temporary graphics context.
#include <plib.h>
#include <wlib.h>
GLDEF_C INT foo(TEXT **pp, INT i) {
if ( i != 1 ) {
if ( (i > 10) || (i < 1) ) {
i = 10 ;
}
for ( ; i > 0 ; i-- ) {
p_sound(5, 320) ;
}
}
return(0) ;
}
#ifdef SHOW_BUG
// Bug here
// C Code TopSpeed Disassembled code
GLDEF_C VOID main(VOID) { // public _main:
// push bx
// push ax
INT i = 1 ; // mov bx,1
wStartup() ; // call near _wStartup
// wStartup() changes bx, though!
// xor ax,ax
foo(NULL, i) ; // call near _foo
// xor bx,bx
p_exit(0) ; // call near _p_exit
// pop ax
// pop bx
// ret 0
}
#else
// No bug here
// C Code TopSpeed Disassembled code
GLDEF_C VOID main(VOID) { // public _main:
// push bx
// push ax
INT i ;
wStartup() ; // call near _wStartup
// wStartup() changes bx, but it gets re-initialized
i = 1 ; // mov bx,1
// xor ax,ax
foo(NULL, i) ; // call near _foo
// xor bx,bx
p_exit(0) ; // call near _p_exit
// pop ax
// pop bx
// ret 0
}
#endif
GLDEF_C INT NEXT_RECORD(PR_ISAMAN *pIsam, INT id) {
INT ret ;
ret = p_send3(pIsam, O_IS_INEXT, id) ;
if ( ret == E_FILE_EOF ) {
p_send3(pIsam, O_IS_IBACK, id) ;
p_send3(pIsam, O_IS_INEXT, id) ;
ret = p_send3(pIsam, O_IS_INEXT, id) ;
}
return(ret) ;
}
Under some circumstances a operation involving index navigation will produce a p_leave(E_FILE_EOF) being called - this is quite distinct from an operation *returning* a false result of E_FILE_EOF. In fact the file read that generates this is not even to do with the .DBF but rather the C_BLOCKER is reading past the end of the .IDX The problem arises in the following circumstance:
What's happened is this, Index A has remained open so the Blocker is not destroyed. When index B is closed and index C is created, the "actualblocks" property that holds the number of blocks that hold index data is not zeroised. Thus the index file may not be extended during a subsequent O_BL_ALLOC as it believes the file to be big enough already. This leads to blocks not being written in the correct position and eventually to a potential read from a non-existent file location.
The work round uses the fact that the property *is* correctly zeroised when an *existing* index is opened as opposed to when a new one is created thus to create an index safely, the sequence should be used:
iId=p_send4(p_isam,O_IS_IOPEN,idxname,P_FREPLACE|P_FUPDATE); p_send3(p_isam,O_IS_ICLOSE,iId); iId=p_send4(p_isam,O_IS_IOPEN,idxname,P_FOPEN|P_FUPDATE);
Back to My home page