diff --git a/Doc/Zsh/mod_db_gdbm.yo b/Doc/Zsh/mod_db_gdbm.yo index 699e9ab..7063690 100644 --- a/Doc/Zsh/mod_db_gdbm.yo +++ b/Doc/Zsh/mod_db_gdbm.yo @@ -49,6 +49,15 @@ item(tt(zgdbmpath) var(parametername))( Put path to database file assigned to var(parametername) into tt(REPLY) scalar. ) +findex(zgdbmclear) +cindex(database concurrent access) +item(tt(zgdbmclear) var(parametername) var(keyname))( +The tied database is enabled for concurrent access only within single Zsh +instance. User must use tt(zsystem flock) to guard that access if it involves +any writes. To refetch a key from database when its change in concurrent +Zsh process is possible, user should use tt(zgdbmclear) passing name of +database and name of the key to refetch. +) findex(zgdbm_tied) cindex(database tied arrays, enumerating) item(tt(zgdbm_tied))( diff --git a/Src/Modules/db_gdbm.c b/Src/Modules/db_gdbm.c index 596a8ae..730abea 100644 --- a/Src/Modules/db_gdbm.c +++ b/Src/Modules/db_gdbm.c @@ -89,6 +89,7 @@ static struct builtin bintab[] = { BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:r", NULL), BUILTIN("zuntie", 0, bin_zuntie, 1, -1, 0, "u", NULL), BUILTIN("zgdbmpath", 0, bin_zgdbmpath, 1, -1, 0, "", NULL), + BUILTIN("zgdbmclear", 0, bin_zgdbmclear, 2, -1, 0, "", NULL), }; #define ROARRPARAMDEF(name, var) \ @@ -260,6 +261,42 @@ bin_zgdbmpath(char *nam, char **args, Options ops, UNUSED(int func)) return 0; } +/**/ +static int +bin_zgdbmclear(char *nam, char **args, Options ops, UNUSED(int func)) +{ + Param pm; + char *pmname, *key; + + pmname = *args++; + key = *args; + + if (!pmname) { + zwarnnam(nam, "parameter name (whose path is to be written to $REPLY) is required"); + return 1; + } + + pm = (Param) paramtab->getnode(paramtab, pmname); + if(!pm) { + zwarnnam(nam, "no such parameter: %s", pmname); + return 1; + } + + if (pm->gsu.h != &gdbm_hash_gsu) { + zwarnnam(nam, "not a tied gdbm parameter: %s", pmname); + return 1; + } + + HashTable ht = pm->u.hash; + HashNode hn = gethashnode2( ht, key ); + Param val_pm = (Param) hn; + if (val_pm) { + val_pm->node.flags &= ~(PM_UPTODATE); + } + + return 0; +} + /* * The param is actual param in hash – always, because * getgdbmnode creates every new key seen. However, it