From dbe68f1a1f67db5bcff9836627bd84f3dbe09b73 Mon Sep 17 00:00:00 2001 From: Przemyslaw Czerpak Date: Thu, 3 Jan 2013 12:31:00 +0000 Subject: [PATCH] 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 --- harbour/ChangeLog.txt | 11 ++++++++ harbour/doc/xhb-diff.txt | 58 ++++++++++++++++++++++++++++++++++---- harbour/src/rdd/dbdetach.c | 4 +-- harbour/src/rtl/hbcom.c | 29 +++++++++++++++++++ 4 files changed, 95 insertions(+), 7 deletions(-) diff --git a/harbour/ChangeLog.txt b/harbour/ChangeLog.txt index dd6ab28d89..2263896bc0 100644 --- a/harbour/ChangeLog.txt +++ b/harbour/ChangeLog.txt @@ -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 diff --git a/harbour/doc/xhb-diff.txt b/harbour/doc/xhb-diff.txt index 54593bcdf9..264d2428ed 100644 --- a/harbour/doc/xhb-diff.txt +++ b/harbour/doc/xhb-diff.txt @@ -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( [|], [] ) --> lSuccess +Then this work area can be attached by other thread using: + DbRequest( [], [], ; + [<@bAreaBlock>], [] ) --> lSuccess +In Harbour above functions are available in XPP emulation library. +There are also core Harbour functions giving this functionality: + hb_dbDetach( [|], [] ) -> + hb_dbRequest( [], [], ; + [<@xCargo>], [] ) -> +This is very powerful mechanism which allows to concurrently access +the same tables, i.e. this PP rules illustrates it: + #xcommand UNLOCK WORKAREA [] => hb_dbDetach( ) + #xcommand LOCK WORKAREA => hb_dbRequest( , .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. diff --git a/harbour/src/rdd/dbdetach.c b/harbour/src/rdd/dbdetach.c index c014bf0f54..f1fde349b5 100644 --- a/harbour/src/rdd/dbdetach.c +++ b/harbour/src/rdd/dbdetach.c @@ -95,8 +95,8 @@ HB_FUNC( HB_DBDETACH ) } /* - * DbRequest( [], [], [<@xCargo>], [] ) - * -> + * hb_dbRequest( [], [], [<@xCargo>], [] ) + * -> */ HB_FUNC( HB_DBREQUEST ) { diff --git a/harbour/src/rtl/hbcom.c b/harbour/src/rtl/hbcom.c index 9b7ccdf627..e7f8bb2fa2 100644 --- a/harbour/src/rtl/hbcom.c +++ b/harbour/src/rtl/hbcom.c @@ -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;