Commit 1698ee43 authored by John P. Willis's avatar John P. Willis
Browse files

Add M14 error for LOCK

parent 50ad320b
Pipeline #745 passed with stage
in 1 minute and 26 seconds
This diff is collapsed.
...@@ -47,6 +47,7 @@ ...@@ -47,6 +47,7 @@
#include "locktab.h" #include "locktab.h"
#include "shmmgr.h" #include "shmmgr.h"
#include "mref.h" #include "mref.h"
#include "transact.h"
union semun { union semun {
int val; /* Value for SETVAL */ int val; /* Value for SETVAL */
...@@ -58,6 +59,8 @@ union semun { ...@@ -58,6 +59,8 @@ union semun {
int semid_locktab; int semid_locktab;
int locktab_list_count(char *key);
void locktab_init(void) void locktab_init(void)
{ {
union semun arg; union semun arg;
...@@ -164,30 +167,127 @@ void lock(char *lockarg, long time_out, char type) ...@@ -164,30 +167,127 @@ void lock(char *lockarg, long time_out, char type)
void locktab_increment(char *key, long timeout) void locktab_increment(char *key, long timeout)
{ {
int nref_ct = locktab_list_count (key);
switch (timeout) { switch (timeout) {
case -1: /* blocking lock (no timeout) */ case -1: /* blocking lock (no timeout) */
for (;;) { if (nref_ct > 1) {
/* this is a lock list */
char *nref;
char tmps[255];
int i;
int successes = 0;
int attempts = 0;
int list_pos = 0;
if (locktab_insert (key) != NULL) { char *attempt_status = (char *) malloc (nref_ct * sizeof (char));
return; NULLPTRCHK(attempt_status,"locktab_increment");
}
else { for (i = 0; i < nref_ct; i++) attempt_status[i] = (char) FALSE;
sleep (1);
}
stcpy (tmps, key);
stcnv_m2c (tmps);
nref = strtok (tmps, "\001\201");
do {
list_pos = 0;
attempts = 0;
successes = 0;
for (;;) {
attempts++;
if (attempt_status[list_pos] == FALSE) {
if (locktab_insert (nref) != NULL) {
successes++;
attempt_status[list_pos] = TRUE;
}
else {
locktab_decrement (nref, -1L);
attempt_status[list_pos] = FALSE;
}
}
nref = strtok (NULL, "\001\201");
if (nref == NULL) break;
list_pos++;
}
} while (successes < nref_ct);
free (attempt_status);
return;
}
else {
for (;;) {
if (locktab_insert (key) != NULL) {
return;
}
else {
sleep (1);
}
}
} }
case 0: /* lock that returns immediately */ case 0: /* lock that returns immediately */
if (locktab_insert (key) != NULL) { if (nref_ct > 1) {
/* this is a lock list */
char *nref;
char tmps[255];
int successes = 0;
int attempts = 0;
stcpy (tmps, key);
stcnv_m2c (tmps);
nref = strtok (tmps, "\001\201");
for (;;) {
attempts++;
if (locktab_insert (nref) != NULL) {
successes++;
}
else {
locktab_decrement (nref, 0L);
test = 0;
return;
}
nref = strtok (NULL, "\001\201");
if (nref == NULL) break;
}
test = 1; test = 1;
return;
} }
else { else {
test = 0;
if (locktab_insert (key) != NULL) {
test = 1;
}
else {
test = 0;
}
} }
break; break;
...@@ -262,6 +362,11 @@ void locktab_decrement(char *key, long timeout) ...@@ -262,6 +362,11 @@ void locktab_decrement(char *key, long timeout)
locktab_ent_t *lck = locktab_find (key); locktab_ent_t *lck = locktab_find (key);
if (tp_level > lck->tp_level) {
ierr = M41;
return;
}
if (lck != NULL) { if (lck != NULL) {
if (lck->ct > 0) lck->ct--; if (lck->ct > 0) lck->ct--;
...@@ -292,6 +397,11 @@ void locktab_unlock_all(void) ...@@ -292,6 +397,11 @@ void locktab_unlock_all(void)
if (lck->owner_job == pid) { if (lck->owner_job == pid) {
if (tp_level > lck->tp_level) {
ierr = M41;
return;
}
lck->ct = 0; lck->ct = 0;
lck->owner_job = 0; lck->owner_job = 0;
strcpy (lck->namespace, "<REUSABLE>"); strcpy (lck->namespace, "<REUSABLE>");
...@@ -345,7 +455,7 @@ locktab_ent_t *locktab_insert(char *key) ...@@ -345,7 +455,7 @@ locktab_ent_t *locktab_insert(char *key)
{ {
locktab_ent_t *l; locktab_ent_t *l;
char chk_ns[255]; char chk_ns[255];
if (key[1] == '%') { if (key[1] == '%') {
snprintf (chk_ns, 255, "SYSTEM"); snprintf (chk_ns, 255, "SYSTEM");
} }
...@@ -371,6 +481,8 @@ locktab_ent_t *locktab_insert(char *key) ...@@ -371,6 +481,8 @@ locktab_ent_t *locktab_insert(char *key)
if (l->owner_job != pid) l->owner_job = pid; if (l->owner_job != pid) l->owner_job = pid;
l->tp_level = tp_level;
ssvn_lock_add (l->nref, l->owner_job, l->ct); ssvn_lock_add (l->nref, l->owner_job, l->ct);
return l; return l;
...@@ -411,6 +523,18 @@ int locktab_count(char *key) ...@@ -411,6 +523,18 @@ int locktab_count(char *key)
return ct; return ct;
} }
int locktab_list_count(char *key)
{
int i;
int lct = 0;
for (i = 0; i < stlen (key); i++) {
if (key[i] == '\001') lct++;
}
return lct;
}
unsigned long locktab_pages(void) unsigned long locktab_pages(void)
{ {
......
...@@ -47,6 +47,7 @@ typedef struct locktab_ent_t { ...@@ -47,6 +47,7 @@ typedef struct locktab_ent_t {
char namespace[255]; char namespace[255];
char nref[NREF_MAXLEN]; char nref[NREF_MAXLEN];
int tp_level;
pid_t owner_job; pid_t owner_job;
int ct; int ct;
......
...@@ -1545,7 +1545,7 @@ set: ...@@ -1545,7 +1545,7 @@ set:
if (ierr > OK) goto err; if (ierr > OK) goto err;
switch (argptr[0]) { switch (argptr[0]) {
case ',': case ',':
switch (argptr[1]) { switch (argptr[1]) {
...@@ -4544,7 +4544,7 @@ off3: ...@@ -4544,7 +4544,7 @@ off3:
expr (NAME); expr (NAME);
if (ierr > OK) goto err; if (ierr > OK) goto err;
stcat (tmp, varnam); stcat (tmp, varnam);
stcat (tmp, "\001\201"); stcat (tmp, "\001\201");
...@@ -4555,6 +4555,7 @@ off3: ...@@ -4555,6 +4555,7 @@ off3:
goto err; goto err;
} }
} }
} }
timeout = (-1L); /* no timeout */ timeout = (-1L); /* no timeout */
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment