2013-01-03 13:30 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
* harbour/src/rtl/hbcom.c
+ added translation for some OS error codes
* harbour/src/rdd/dbdetach.c
! minor correction in comment
* harbour/doc/xhb-diff.txt
+ added new section:
THREAD LOCAL WORK AREAS AND CONCURRENT WORK AREA ACCESS
This commit is contained in:
@@ -10,6 +10,17 @@
|
||||
* Change, ! Fix, % Optimization, + Addition, - Removal, ; Comment
|
||||
*/
|
||||
|
||||
2013-01-03 13:30 UTC+0100 Przemyslaw Czerpak (druzus/at/poczta.onet.pl)
|
||||
* harbour/src/rtl/hbcom.c
|
||||
+ added translation for some OS error codes
|
||||
|
||||
* harbour/src/rdd/dbdetach.c
|
||||
! minor correction in comment
|
||||
|
||||
* harbour/doc/xhb-diff.txt
|
||||
+ added new section:
|
||||
THREAD LOCAL WORK AREAS AND CONCURRENT WORK AREA ACCESS
|
||||
|
||||
2012-12-28 14:01 UTC+0100 Viktor Szakats (harbour syenar.net)
|
||||
* src/rtl/teditor.prg
|
||||
! fix to fix to fix. I'd appreciate if someone else
|
||||
|
||||
@@ -1980,7 +1980,7 @@ have to be synced by user and automatic synchronization here will
|
||||
strongly reduce scalability.
|
||||
|
||||
Harbour also support xBase++ compatible MT API with SYNC and CLASS SYNC
|
||||
methods, SIGNAL and THREAD classes, workarea zones and thread functions.
|
||||
methods, SIGNAL and THREAD classes, work area zones and thread functions.
|
||||
It allows to easy port xbase++ code to Harbour. The main difference
|
||||
between Harbour and xbase++ is write protection to complex items.
|
||||
Harbour gives only read protection so threads can access the same
|
||||
@@ -2023,11 +2023,10 @@ it in last years. This feature in xHarbour was implemented only in .c
|
||||
code generated by xHarbour compiler (-gc[0-3] output) so it was never
|
||||
working with .hrb (-gh) files or some interpreters like xBaseScript.
|
||||
xHarbour has support for SYNC methods which were designed to replicate
|
||||
xBase++ functionality but their real behavior is not xBase++ and Harbour
|
||||
compatible at all. It seems to be close to SYNC CLASS method in xBase++
|
||||
xBase++ functionality but their real behavior is neither xBase++ nor
|
||||
Harbour compatible. It seems to be close to SYNC CLASS methods in xBase++
|
||||
and Harbour though it's not exactly the same. There is no support for
|
||||
real SYNC methods like in xBase++ and xBase++ MT programming functions
|
||||
and classes.
|
||||
real xBase++ SYNC methods and xBase++ MT programming functions and classes.
|
||||
|
||||
In summary MT mode in xHarbour looks like a work in progress, started few
|
||||
years ago and never finished. Instead some other core code modifications
|
||||
@@ -2052,6 +2051,55 @@ far from current Harbour functionality and quality.
|
||||
|
||||
|
||||
|
||||
### THREAD LOCAL WORK AREAS AND CONCURRENT WORK AREA ACCESS ###
|
||||
=====================================================================
|
||||
In Harbour and xBase++ work areas are local to the thread. It means
|
||||
that each thread has its own independent work areas and aliases.
|
||||
Anyhow it's possible to move work area from one thread to other one
|
||||
using known from xBase++ zero space. In xBase++ each thread can
|
||||
move his work area to zero space using:
|
||||
DbRelease( [<nWorkArea>|<cAlias>], [<bAreaBlock>] ) --> lSuccess
|
||||
Then this work area can be attached by other thread using:
|
||||
DbRequest( [<cAlias>], [<lFreeArea>], ;
|
||||
[<@bAreaBlock>], [<lWait>] ) --> lSuccess
|
||||
In Harbour above functions are available in XPP emulation library.
|
||||
There are also core Harbour functions giving this functionality:
|
||||
hb_dbDetach( [<nWorkArea>|<cAlias>], [<xCargo>] ) -> <lSuccess>
|
||||
hb_dbRequest( [<cAlias>], [<lFreeArea>], ;
|
||||
[<@xCargo>], [<lWait>] ) -> <lSuccess>
|
||||
This is very powerful mechanism which allows to concurrently access
|
||||
the same tables, i.e. this PP rules illustrates it:
|
||||
#xcommand UNLOCK WORKAREA [<cAlias>] => hb_dbDetach( <cAlias> )
|
||||
#xcommand LOCK WORKAREA <cAlias> => hb_dbRequest( <cAlias>, .T.,, .T. )
|
||||
after opening the table (USE) thread executes
|
||||
UNLOCK WORKAREA
|
||||
and move work area to zero space. Then each thread which wants to make
|
||||
some operations on work area has to encapsulate it in lock/unlock code,
|
||||
i.e.:
|
||||
LOCK WORKAREA "DOCUMENTS"
|
||||
COUNT TO nInvoices FOR year( DOCUMENTS->DATE ) == year( date() )
|
||||
UNLOCK WORKAREA
|
||||
|
||||
In xHarbour by default work areas are global to the application and there
|
||||
is no protection mechanism against concurrent access so if two threads try
|
||||
to access the same work area in the same time they can corrupt internal
|
||||
RDD data. It means that for safe concurrent WA access in xHarbour user have
|
||||
to create his own protection mechanism (some different version of LOCAL
|
||||
WORKAREA / UNLOCK WORKAREA commands using some other synchronization
|
||||
methods available in xHarbour, i.e. mutexes).
|
||||
Later support for thread local work areas was added to xHarbour but
|
||||
without any mechanism which allows to move work area from one thread to
|
||||
another. This can be controlled by global SET (SETs are global in xHarbour)
|
||||
_SET_WORKAREAS_SHARED
|
||||
Setting it to .T. disables global work areas and switches to thread local
|
||||
ones.
|
||||
There is no technical or mathematical reason to keep such strange
|
||||
implementation because it does not give any new functionality to
|
||||
programmer in comparison to xBase++ and Harbour but allows to easy
|
||||
corrupt RDD internals.
|
||||
|
||||
|
||||
|
||||
### HARBOUR TASKS AND MT SUPPORT IN DOS ###
|
||||
=================================================
|
||||
Harbour supports threads also in systems without native thread support.
|
||||
|
||||
@@ -95,8 +95,8 @@ HB_FUNC( HB_DBDETACH )
|
||||
}
|
||||
|
||||
/*
|
||||
* DbRequest( [<cAlias>], [<lFreeArea>], [<@xCargo>], [<lWait>] )
|
||||
* -> <lSuccess>
|
||||
* hb_dbRequest( [<cAlias>], [<lFreeArea>], [<@xCargo>], [<lWait>] )
|
||||
* -> <lSuccess>
|
||||
*/
|
||||
HB_FUNC( HB_DBREQUEST )
|
||||
{
|
||||
|
||||
@@ -326,9 +326,19 @@ static void hb_comSetOsError( PHB_COM pCom, HB_BOOL fError )
|
||||
pCom->error = HB_COM_ERR_TIMEOUT;
|
||||
break;
|
||||
case EACCES:
|
||||
#if defined( ETXTBSY )
|
||||
case ETXTBSY:
|
||||
#endif
|
||||
#if defined( EPERM )
|
||||
case EPERM:
|
||||
#endif
|
||||
pCom->error = HB_COM_ERR_ACCESS;
|
||||
break;
|
||||
case ENOTTY:
|
||||
case ENOENT:
|
||||
#if defined( ENOTDIR )
|
||||
case ENOTDIR:
|
||||
#endif
|
||||
pCom->error = HB_COM_ERR_NOCOM;
|
||||
break;
|
||||
default:
|
||||
@@ -1346,6 +1356,14 @@ static void hb_comSetOsError( PHB_COM pCom, BOOL fError )
|
||||
case ERROR_TIMEOUT:
|
||||
pCom->error = HB_COM_ERR_TIMEOUT;
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
case ERROR_SHARING_VIOLATION:
|
||||
pCom->error = HB_COM_ERR_BUSY;
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
pCom->error = HB_COM_ERR_NOCOM;
|
||||
break;
|
||||
default:
|
||||
pCom->error = HB_COM_ERR_OTHER;
|
||||
break;
|
||||
@@ -2065,6 +2083,17 @@ static void hb_comSetOsError( PHB_COM pCom, APIRET rc )
|
||||
case NO_ERROR:
|
||||
pCom->error = 0;
|
||||
break;
|
||||
case ERROR_TIMEOUT:
|
||||
pCom->error = HB_COM_ERR_TIMEOUT;
|
||||
break;
|
||||
case ERROR_ACCESS_DENIED:
|
||||
case ERROR_SHARING_VIOLATION:
|
||||
pCom->error = HB_COM_ERR_BUSY;
|
||||
break;
|
||||
case ERROR_FILE_NOT_FOUND:
|
||||
case ERROR_PATH_NOT_FOUND:
|
||||
pCom->error = HB_COM_ERR_NOCOM;
|
||||
break;
|
||||
default:
|
||||
pCom->error = HB_COM_ERR_OTHER;
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user