Thread safe strings and times

Times and string attributes in the realtime database can not be accessed in an atomic
operation and thus needs special consideration when handled in two different threads or
processes. The problem is that when one thread is writing a time or string attribute, another
thread can read the attribute before the write is finished, and thus read a value that
contains parts of both the previous and the new value. To avoid this the read and write
operations should be protected by a lock. There are two locks, one for time attributes and one
for string attributes.

Time lock

The time lock is used for attributes of type pwr_tTime and pwr_tDeltaTime. When a time
attribute is read or written, the lock should be set. The following plc function objects will
use the lock to protect the reading or writing of the time value.
StoATv, StoDTv, CStoATv, CStoDTv, StoDTp, StoATp, CStoDTp, CStoATp, GetATp, GetDTp, GetATv,
GetDTv, CurrentTime.

Note that other time objects are not protected by the lock. It's not safe to use the output
from for example a AtAdd in another Plc thread or an application program. In this case the
time should first be stored in an ATv object.

To read and write times, applications should use these gdh functions
void gdh_GetTimeDL( pwr_tTime *atp, pwr_tTime *time);
void gdh_SetTimeDL( pwr_tTime *atp, pwr_tTime *time);
void gdh_GetDeltaTimeDL( pwr_tDeltaTime *dtp, pwr_tDeltaTime *time);
void gdh_SetDeltaTimeDL( pwr_tDeltaTime *dtp, pwr_tDeltaTime *time);
pwr_tStatus gdh_GetObjectInfoTime( char *name, pwr_tTime *time);
pwr_tStatus gdh_SetObjectInfoTime( char *name, pwr_tTime *time);
pwr_tStatus gdh_GetObjectInfoDeltaTime( char *name, pwr_tDeltaTime *time);
pwr_tStatus gdh_SetObjectInfoDeltaTime( char *name, pwr_tDeltaTime *time);

Before using any of these functions, the time lock has to be initialized by the application
with a call to lck_Create(), eg
lck_Create(&sts, lck_eLock_Time);

String lock

The string lock is used for string attributes. The following plc function objects will use
the lock. StoSv, CStoSv, StoSp, CStoSp, StoNumSp, CStoNumSp, GetSp, GetSv.

Other string objects are not protected by the lock and the string values in these objects
should not be read or written in other Plc threads or in application programs.

To read and write string, applications should use these gdh functions

void gdh_GetStrDL( char *sp, char *str, int size);
void gdh_SetStrDL( char *sp, char *str, int size);
pwr_tStatus gdh_GetObjectInfoStr( char *name, char *str, int size);
pwr_tStatus gdh_SetObjectInfoStr( char *name, char *str, int size);

Before using any of these functions, the string lock has to be initialized by the application
with a call to lck_Create(), eg
lck_Create(&sts, lck_eLock_Str);