version 1.1, 2025/01/19 02:04:04
|
version 1.9, 2025/04/13 04:22:43
|
Line 1
|
Line 1
|
/* |
/* |
* * |
* $Id$ |
* * * |
|
* * * |
|
* *************** |
|
* * * * * |
|
* * MUMPS * |
|
* * * * * |
|
* *************** |
|
* * * |
|
* * * |
|
* * |
|
* |
|
* transact.c |
|
* FreeM transaction processing support |
* FreeM transaction processing support |
* |
* |
* |
* |
* Author: Serena Willis <jpw@coherent-logic.com> |
* Author: Serena Willis <snw@coherent-logic.com> |
* Copyright (C) 1998 MUG Deutschland |
* Copyright (C) 1998 MUG Deutschland |
* Copyright (C) 2020 Coherent Logic Development LLC |
* Copyright (C) 2020, 2025 Coherent Logic Development LLC |
* |
* |
* |
* |
* This file is part of FreeM. |
* This file is part of FreeM. |
Line 35
|
Line 23
|
* You should have received a copy of the GNU Affero Public License |
* You should have received a copy of the GNU Affero Public License |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* along with FreeM. If not, see <https://www.gnu.org/licenses/>. |
* |
* |
|
* $Log$ |
|
* Revision 1.9 2025/04/13 04:22:43 snw |
|
* Fix snprintf calls |
|
* |
|
* Revision 1.8 2025/04/10 01:24:39 snw |
|
* Remove C++ style comments |
|
* |
|
* Revision 1.7 2025/04/09 19:52:02 snw |
|
* Eliminate as many warnings as possible while building with -Wall |
|
* |
|
* Revision 1.6 2025/03/24 04:13:12 snw |
|
* Replace action macro dat with fra_dat to avoid symbol conflict on OS/2 |
|
* |
|
* Revision 1.5 2025/03/24 02:54:47 snw |
|
* Transaction compat fixes for OS/2 |
|
* |
|
* Revision 1.4 2025/03/09 19:50:47 snw |
|
* Second phase of REUSE compliance and header reformat |
|
* |
|
* |
|
* SPDX-FileCopyrightText: (C) 2025 Coherent Logic Development LLC |
|
* SPDX-License-Identifier: AGPL-3.0-or-later |
**/ |
**/ |
|
|
#include <string.h> |
#include <string.h> |
Line 55
|
Line 65
|
#define FALSE 0 |
#define FALSE 0 |
#define TRUE 1 |
#define TRUE 1 |
|
|
#if !defined(__OpenBSD__) && !defined(__APPLE__) |
#if !defined(__OpenBSD__) && !defined(__APPLE__) && !defined(__OS2__) |
union semun { |
union semun { |
int val; /* Value for SETVAL */ |
int val; /* Value for SETVAL */ |
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ |
struct semid_ds *buf; /* Buffer for IPC_STAT, IPC_SET */ |
Line 76 tp_transaction transactions[TP_MAX_NEST]
|
Line 86 tp_transaction transactions[TP_MAX_NEST]
|
void tp_init(void) |
void tp_init(void) |
{ |
{ |
union semun arg; |
union semun arg; |
char err[255]; |
|
key_t tp_sk; |
key_t tp_sk; |
|
|
tp_sk = ftok (config_file, 4); |
tp_sk = ftok (config_file, 4); |
Line 117 short tp_get_sem(void)
|
Line 126 short tp_get_sem(void)
|
|
|
char msgbuf[100]; |
char msgbuf[100]; |
|
|
snprintf (msgbuf, 99, "tp_get_sem: process %d attempting to acquire transaction processing semaphore", pid); |
snprintf (msgbuf, sizeof (msgbuf) - 1, "tp_get_sem: process %d attempting to acquire transaction processing semaphore", pid); |
m_log (1, msgbuf); |
m_log (1, msgbuf); |
|
|
|
|
/* our process already owns the semaphore */ |
/* our process already owns the semaphore */ |
if (shm_config->hdr->tp_owner == pid) { |
if (shm_config->hdr->tp_owner == pid) { |
|
|
snprintf (msgbuf, 99, "tp_get_sem: process %d increments transaction processing semaphore counter", pid); |
snprintf (msgbuf, sizeof (msgbuf) - 1, "tp_get_sem: process %d increments transaction processing semaphore counter", pid); |
m_log (1, msgbuf); |
m_log (1, msgbuf); |
|
|
|
|
Line 149 short tp_get_sem(void)
|
Line 158 short tp_get_sem(void)
|
shm_config->hdr->tp_owner = pid; |
shm_config->hdr->tp_owner = pid; |
shm_config->hdr->tp_semctr = 1; |
shm_config->hdr->tp_semctr = 1; |
|
|
snprintf (msgbuf, 99, "tp_get_sem: process %d takes transaction processing semaphore", pid); |
snprintf (msgbuf, sizeof (msgbuf) - 1, "tp_get_sem: process %d takes transaction processing semaphore", pid); |
m_log (1, msgbuf); |
m_log (1, msgbuf); |
|
|
|
|
Line 160 short tp_get_sem(void)
|
Line 169 short tp_get_sem(void)
|
return TRUE; |
return TRUE; |
} |
} |
|
|
snprintf (msgbuf, 99, "tp_get_sem: process %d attempting to acquire transaction processing semaphore (tries = %d)", pid, tries); |
snprintf (msgbuf, sizeof (msgbuf) - 1, "tp_get_sem: process %d attempting to acquire transaction processing semaphore (tries = %d)", pid, tries); |
m_log (1, msgbuf); |
m_log (1, msgbuf); |
|
|
|
|
Line 194 void tp_release_sem(void)
|
Line 203 void tp_release_sem(void)
|
} |
} |
|
|
|
|
snprintf (msgbuf, 99, "tp_get_sem: process %d releases transaction processing semaphore", pid); |
snprintf (msgbuf, sizeof (msgbuf) - 1, "tp_get_sem: process %d releases transaction processing semaphore", pid); |
m_log (1, msgbuf); |
m_log (1, msgbuf); |
|
|
|
|
Line 207 void tp_release_sem(void)
|
Line 216 void tp_release_sem(void)
|
fprintf (stderr, "tp_release_sem: daemon process decrements critical section counter\r\n"); |
fprintf (stderr, "tp_release_sem: daemon process decrements critical section counter\r\n"); |
} |
} |
|
|
snprintf (msgbuf, 99, "tp_get_sem: process %d decrements transaction processing semaphore counter", pid); |
snprintf (msgbuf, sizeof (msgbuf) - 1, "tp_get_sem: process %d decrements transaction processing semaphore counter", pid); |
m_log (1, msgbuf); |
m_log (1, msgbuf); |
|
|
shm_config->hdr->tp_semctr--; |
shm_config->hdr->tp_semctr--; |
Line 221 int tp_tstart(char *tp_id, short serial,
|
Line 230 int tp_tstart(char *tp_id, short serial,
|
if (tp_level == TP_MAX_NEST) { |
if (tp_level == TP_MAX_NEST) { |
char m[256]; |
char m[256]; |
|
|
snprintf (m, 256, "Attempt to exceed TP_MAX_NEST. Transaction aborted.\r\n\201"); |
snprintf (m, sizeof (m) - 1, "Attempt to exceed TP_MAX_NEST. Transaction aborted.\r\n\201"); |
write_m (m); |
write_m (m); |
|
|
return FALSE; |
return FALSE; |
Line 266 int tp_add_op(short islock, short action
|
Line 275 int tp_add_op(short islock, short action
|
if (transactions[tp_level].opcount == TP_MAX_OPS) { |
if (transactions[tp_level].opcount == TP_MAX_OPS) { |
char m[256]; |
char m[256]; |
|
|
snprintf (m, 256, "Attempt to exceed TP_MAX_OPS at transaction level %d. Rolling back.\r\n\201", tp_level); |
snprintf (m, sizeof (m) - 1, "Attempt to exceed TP_MAX_OPS at transaction level %d. Rolling back.\r\n\201", tp_level); |
write_m (m); |
write_m (m); |
|
|
free (gr); |
free (gr); |
Line 311 int tp_add_op(short islock, short action
|
Line 320 int tp_add_op(short islock, short action
|
transactions[tp_level].ops[oc].is_lock = islock; |
transactions[tp_level].ops[oc].is_lock = islock; |
transactions[tp_level].ops[oc].action = action; |
transactions[tp_level].ops[oc].action = action; |
|
|
stcpy (&transactions[tp_level].ops[oc].key, key); |
stcpy ((char *) &transactions[tp_level].ops[oc].key, key); |
stcpy (&transactions[tp_level].ops[oc].data, data); |
stcpy ((char *) &transactions[tp_level].ops[oc].data, data); |
|
|
|
|
return TRUE; |
return TRUE; |
Line 384 int tp_trollback(int levels)
|
Line 393 int tp_trollback(int levels)
|
register int i; |
register int i; |
register int j; |
register int j; |
|
|
// for (i = 0; i < levels; i++) { |
|
for (i = tp_level; i >= (((tp_level - levels) >= 0) ? tp_level - levels : 0); i--) { |
for (i = tp_level; i >= (((tp_level - levels) >= 0) ? tp_level - levels : 0); i--) { |
|
|
for (j = 1; j <= transactions[i].opcount; j++) { |
for (j = 1; j <= transactions[i].opcount; j++) { |
Line 495 void tp_get_op_name(char *buf, const sho
|
Line 503 void tp_get_op_name(char *buf, const sho
|
strcpy (buf, "GET"); |
strcpy (buf, "GET"); |
break; |
break; |
|
|
case dat: |
case fra_dat: |
strcpy (buf, "$DATA"); |
strcpy (buf, "$DATA"); |
break; |
break; |
|
|