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:
Przemyslaw Czerpak
2013-01-03 12:31:00 +00:00
parent 3ba0fe6d53
commit dbe68f1a1f
4 changed files with 95 additions and 7 deletions

View File

@@ -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

View File

@@ -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.

View File

@@ -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 )
{

View File

@@ -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;