|
|
| 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; |