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 @@
#include "locktab.h"
#include "shmmgr.h"
#include "mref.h"
#include "transact.h"
union semun {
int val; /* Value for SETVAL */
......@@ -58,6 +59,8 @@ union semun {
int semid_locktab;
int locktab_list_count(char *key);
void locktab_init(void)
{
union semun arg;
......@@ -165,10 +168,69 @@ void lock(char *lockarg, long time_out, char type)
void locktab_increment(char *key, long timeout)
{
int nref_ct = locktab_list_count (key);
switch (timeout) {
case -1: /* blocking lock (no timeout) */
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;
char *attempt_status = (char *) malloc (nref_ct * sizeof (char));
NULLPTRCHK(attempt_status,"locktab_increment");
for (i = 0; i < nref_ct; i++) attempt_status[i] = (char) FALSE;
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) {
......@@ -179,10 +241,46 @@ void locktab_increment(char *key, long timeout)
}
}
}
case 0: /* lock that returns immediately */
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;
return;
}
else {
if (locktab_insert (key) != NULL) {
test = 1;
}
......@@ -190,6 +288,8 @@ void locktab_increment(char *key, long timeout)
test = 0;
}
}
break;
case 1: /* special case: lock with 1-second timeout */
......@@ -262,6 +362,11 @@ void locktab_decrement(char *key, long timeout)
locktab_ent_t *lck = locktab_find (key);
if (tp_level > lck->tp_level) {
ierr = M41;
return;
}
if (lck != NULL) {
if (lck->ct > 0) lck->ct--;
......@@ -292,6 +397,11 @@ void locktab_unlock_all(void)
if (lck->owner_job == pid) {
if (tp_level > lck->tp_level) {
ierr = M41;
return;
}
lck->ct = 0;
lck->owner_job = 0;
strcpy (lck->namespace, "<REUSABLE>");
......@@ -371,6 +481,8 @@ locktab_ent_t *locktab_insert(char *key)
if (l->owner_job != pid) l->owner_job = pid;
l->tp_level = tp_level;
ssvn_lock_add (l->nref, l->owner_job, l->ct);
return l;
......@@ -411,6 +523,18 @@ int locktab_count(char *key)
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)
{
......
......@@ -47,6 +47,7 @@ typedef struct locktab_ent_t {
char namespace[255];
char nref[NREF_MAXLEN];
int tp_level;
pid_t owner_job;
int ct;
......
......@@ -4555,6 +4555,7 @@ off3:
goto err;
}
}
}
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