00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include "rcs_defs.hh"
00015
00016 #ifdef EXTERN_C_STD_HEADERS
00017 extern "C"
00018 {
00019 #endif
00020
00021
00022 #ifdef UNDER_CE
00023 #include <winbase.h>
00024 #endif
00025
00026 #ifndef UNDER_CE
00027 #include <stdio.h>
00028 #include <stddef.h>
00029 #include <sys/stat.h>
00030 #include <sys/types.h>
00031 #include <errno.h>
00032 #endif
00033 #include <string.h>
00034 #include <stdlib.h>
00035
00036 #ifdef VXWORKS
00037 #include <taskLib.h>
00038 #include <intLib.h>
00039 #endif
00040
00041 #ifdef lynxosPC
00042 #include <fa.h>
00043 #include <kernel.h>
00044 #endif
00045
00046 #ifdef EXTERN_C_STD_HEADERS
00047 }
00048 #endif
00049
00050 #include "rcs_prnt.hh"
00051
00052 #ifdef VXWORKS
00053 typedef int key_t;
00054 #endif
00055
00056 #include "cms.hh"
00057 #include "shmem.hh"
00058 #include "shm.hh"
00059
00060 #include "memsem.hh"
00061 #include "timer.hh"
00062
00063 #ifdef UNDER_CE
00064 #include "rcs_ce.h"
00065 #endif
00066
00067
00068
00069 #include "autokey.h"
00070
00071
00072 #ifndef WIN32
00073 #define MODE (0777)
00074 #else
00075 #define MODE (0)
00076 #endif
00077
00078 #ifdef lynxosPC
00079 struct fa_info *fa_ptr = NULL;
00080 #endif
00081
00082 static double last_non_zero_x;
00083 static double last_x;
00084
00085 static int
00086 not_zero (volatile double x)
00087 {
00088 last_x = x;
00089 if (x < -1E-6 && last_x < -1E-6)
00090 {
00091 last_non_zero_x = x;
00092 return 1;
00093 }
00094 if (x > 1E-6 && last_x > 1E-6)
00095 {
00096 last_non_zero_x = x;
00097 return 1;
00098 }
00099 return 0;
00100 }
00101
00102
00103
00104
00105 SHMEM::SHMEM (char *n, long s, int nt, key_t k, int m):
00106 CMS (s)
00107 {
00108
00109 shm = NULL;
00110
00111
00112
00113 master = m;
00114 key = k;
00115
00116
00117 open ();
00118 }
00119
00120
00121 SHMEM::SHMEM (char *bufline, char *procline, int set_to_server,
00122 int set_to_master):
00123 CMS (bufline, procline, set_to_server)
00124 {
00125
00126 shm = NULL;
00127 sem = NULL;
00128 sem_delay = 0.00001;
00129 char *semdelay_equation;
00130 use_os_sem = 1;
00131 use_os_sem_only = 1;
00132 mutex_type = OS_SEM_MUTEX;
00133 bsem_key = -1;
00134 second_read = 0;
00135
00136 if (status < 0)
00137 {
00138 rcs_print_error ("SHMEM: status = %d\n", status);
00139 return;
00140 }
00141
00142
00143 #ifndef UNDER_CE
00144 if (sscanf (bufline, "%*s %*s %*s %*s %*s %*s %*s %*s %*s %d", &key) != 1)
00145 {
00146 rcs_print_error ("SHMEM: Invalid configuration file format.\n");
00147 return;
00148 }
00149 #else
00150 char *word[32];
00151 if (separate_words (word, 10, bufline) != 10)
00152 {
00153 rcs_print_error ("CMS: Error in buffer line from config file.\n");
00154 rcs_print_error ("%s\n", bufline);
00155 status = CMS_CONFIG_ERROR;
00156 return;
00157 }
00158 key = atol (word[9]);
00159 #endif
00160
00161 master = is_local_master;
00162 if (1 == set_to_master)
00163 {
00164 master = 1;
00165 }
00166 else if (-1 == set_to_master)
00167 {
00168 master = 0;
00169 }
00170
00171 #ifndef UNDER_CE
00172 if (NULL != (semdelay_equation = strstr (proclineupper, "SEMDELAY=")))
00173 {
00174 sem_delay = strtod (semdelay_equation + 9, (char **) NULL);
00175 }
00176 else if (NULL != (semdelay_equation = strstr (buflineupper, "SEMDELAY=")))
00177 {
00178 sem_delay = strtod (semdelay_equation + 9, (char **) NULL);
00179 }
00180 #endif
00181
00182 if (NULL != (semdelay_equation = strstr (buflineupper, "BSEM=")))
00183 {
00184 #ifndef UNDER_CE
00185 bsem_key = strtol (semdelay_equation + 5, (char **) NULL, 0);
00186 #else
00187 bsem_key = atol (semdelay_equation + 5);
00188 #endif
00189 }
00190
00191 if (NULL != strstr (buflineupper, "MUTEX=NONE"))
00192 {
00193 mutex_type = NO_MUTEX;
00194 use_os_sem = 0;
00195 use_os_sem_only = 0;
00196 }
00197
00198 if (NULL != strstr (buflineupper, "MUTEX=OS_SEM"))
00199 {
00200 mutex_type = OS_SEM_MUTEX;
00201 use_os_sem = 1;
00202 use_os_sem_only = 1;
00203 }
00204
00205 if (NULL != strstr (buflineupper, "MUTEX=NO_INTERRUPTS"))
00206 {
00207 mutex_type = NO_INTERRUPTS_MUTEX;
00208 use_os_sem = 0;
00209 use_os_sem_only = 0;
00210 }
00211
00212 if (NULL != strstr (buflineupper, "MUTEX=NO_SWITCHING"))
00213 {
00214 mutex_type = NO_SWITCHING_MUTEX;
00215 #ifdef lynxosPC
00216 if (fa_ptr == NULL)
00217 {
00218 fa_ptr = fast_info_attach ((char *) 0xC0000000);
00219 }
00220 #endif
00221 use_os_sem = 0;
00222 use_os_sem_only = 0;
00223 }
00224
00225 if (NULL != strstr (buflineupper, "MUTEX=MAO"))
00226 {
00227 mutex_type = MAO_MUTEX;
00228 use_os_sem = 0;
00229 use_os_sem_only = 0;
00230 }
00231
00232 if (NULL != strstr (buflineupper, "MAO_W_OS_SEM"))
00233 {
00234 mutex_type = MAO_MUTEX_W_OS_SEM;
00235 use_os_sem = 1;
00236 use_os_sem_only = 0;
00237 }
00238
00239
00240 open ();
00241 }
00242
00243 SHMEM::~SHMEM ()
00244 {
00245
00246 close ();
00247 }
00248
00249
00250
00251
00252 int
00253 SHMEM::open ()
00254 {
00255
00256 sem = NULL;
00257 shm = NULL;
00258 bsem = NULL;
00259 shm_addr_offset = NULL;
00260 second_read = 0;
00261 autokey_table_size = 0;
00262
00263 if (use_autokey_for_connection_number)
00264 {
00265 autokey_table_size = sizeof (AUTOKEY_TABLE_ENTRY) * total_connections;
00266 }
00267
00268
00269 if (master)
00270 {
00271 shm = new RCS_SHAREDMEM (key, size, RCS_SHAREDMEM_CREATE, (int) MODE);
00272 if (shm->addr == NULL)
00273 {
00274 switch (shm->create_errno)
00275 {
00276 #ifndef UNDER_CE
00277 case EACCES:
00278 status = CMS_PERMISSIONS_ERROR;
00279 break;
00280
00281 case EEXIST:
00282 status = CMS_RESOURCE_CONFLICT_ERROR;
00283 break;
00284
00285 case ENOMEM:
00286 case ENOSPC:
00287 status = CMS_CREATE_ERROR;
00288 break;
00289
00290 #endif
00291
00292 default:
00293 status = CMS_MISC_ERROR;
00294 }
00295 delete shm;
00296 shm = NULL;
00297 return -1;
00298 }
00299 if (use_os_sem)
00300 {
00301 sem =
00302 new RCS_SEMAPHORE (key, RCS_SEMAPHORE_CREATE, timeout, (int) MODE,
00303 (use_os_sem_only != 0));
00304 if (NULL == sem)
00305 {
00306 rcs_print_error ("CMS: couldn't create RCS_SEMAPHORE.\n");
00307 rcs_print_error (" Possibly out of memory?\n");
00308 status = CMS_CREATE_ERROR;
00309 return -1;
00310 }
00311 if (!sem->valid ())
00312 {
00313 rcs_print_error ("CMS: RCS_SEMAPHORE is invalid.\n");
00314 status = CMS_MISC_ERROR;
00315 return -1;
00316 }
00317 }
00318 if (bsem_key > 0)
00319 {
00320 #ifndef WIN32
00321 bsem = new RCS_SEMAPHORE (bsem_key, RCS_SEMAPHORE_CREATE,
00322 timeout, (int) MODE, 0);
00323 if (NULL == bsem)
00324 {
00325 rcs_print_error ("CMS: couldn't create RCS_SEMAPHORE.\n");
00326 rcs_print_error (" Possibly out of memory?\n");
00327 status = CMS_CREATE_ERROR;
00328 return -1;
00329 }
00330 if (!bsem->valid ())
00331 {
00332 rcs_print_error ("CMS: RCS_SEMAPHORE is invalid.\n");
00333 status = CMS_MISC_ERROR;
00334 return -1;
00335 }
00336 #else
00337 char bsem_event_name[80];
00338 #ifndef NO_STDIO
00339 sprintf (bsem_event_name, "event%d", bsem_key);
00340 #else
00341 strcpy (bsem_event_name, "event");
00342 _itoa (bsem_key, bsem_event_name + 5, 10);
00343 #endif
00344 #ifndef UNDER_CE
00345 SECURITY_ATTRIBUTES sa;
00346 SECURITY_DESCRIPTOR sd;
00347 if (FALSE ==
00348 InitializeSecurityDescriptor (&sd,
00349 SECURITY_DESCRIPTOR_REVISION))
00350 {
00351 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00352 "Can not initailize security descriptor.\n");
00353 status = CMS_MISC_ERROR;
00354 return -1;
00355 }
00356 sa.nLength = sizeof (SECURITY_ATTRIBUTES);
00357 sa.lpSecurityDescriptor = &sd;
00358 sa.bInheritHandle = TRUE;
00359 bsem = CreateEvent (&sa, TRUE, FALSE, bsem_event_name);
00360 #else
00361 #ifdef UNICODE
00362 wchar_t wbsem_event_name[80];
00363 RCS_CE_ASCII_TO_UNICODE (wbsem_event_name, bsem_event_name, 80);
00364 bsem = CreateEvent (NULL, TRUE, FALSE, wbsem_event_name);
00365 #else
00366 bsem = CreateEvent (NULL, TRUE, FALSE, bsem_event_name);
00367 #endif
00368 #endif
00369 if (NULL == bsem)
00370 {
00371 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00372 "CreateEvent error:");
00373 }
00374 #endif
00375 }
00376 in_buffer_id = 0;
00377 }
00378 else
00379 {
00380 shm = new RCS_SHAREDMEM (key, size, RCS_SHAREDMEM_NOCREATE);
00381 if (NULL == shm)
00382 {
00383 rcs_print_error
00384 ("CMS: couldn't create RCS_SHAREDMEM(%d(0x%X), %d(0x%X), RCS_SHAREDMEM_NOCREATE).\n",
00385 key, key, size, size);
00386 status = CMS_CREATE_ERROR;
00387 return -1;
00388 }
00389 if (shm->addr == NULL)
00390 {
00391 switch (shm->create_errno)
00392 {
00393 #ifndef UNDER_CE
00394 case EACCES:
00395 status = CMS_PERMISSIONS_ERROR;
00396 break;
00397
00398 case EEXIST:
00399 status = CMS_RESOURCE_CONFLICT_ERROR;
00400 break;
00401
00402 case ENOENT:
00403 status = CMS_NO_MASTER_ERROR;
00404 break;
00405
00406 case ENOMEM:
00407 case ENOSPC:
00408 status = CMS_CREATE_ERROR;
00409 break;
00410
00411 #endif
00412
00413 default:
00414 status = CMS_MISC_ERROR;
00415 }
00416 delete shm;
00417 shm = NULL;
00418 return -1;
00419 }
00420 if (use_os_sem)
00421 {
00422 sem = new RCS_SEMAPHORE (key, RCS_SEMAPHORE_NOCREATE, timeout);
00423 if (NULL == sem)
00424 {
00425 rcs_print_error ("CMS: couldn't create RCS_SEMAPHORE.\n");
00426 rcs_print_error (" Possibly out of memory?\n");
00427 status = CMS_CREATE_ERROR;
00428 return -1;
00429 }
00430 if (!sem->valid ())
00431 {
00432 rcs_print_error ("CMS: RCS_SEMAPHORE is invalid.\n");
00433 status = CMS_MISC_ERROR;
00434 return -1;
00435 }
00436 }
00437 if (bsem_key > 0)
00438 {
00439 #ifndef WIN32
00440 bsem =
00441 new RCS_SEMAPHORE (bsem_key, RCS_SEMAPHORE_NOCREATE, timeout);
00442 if (NULL == bsem)
00443 {
00444 rcs_print_error ("CMS: couldn't create RCS_SEMAPHORE.\n");
00445 rcs_print_error (" Possibly out of memory?\n");
00446 status = CMS_CREATE_ERROR;
00447 return -1;
00448 }
00449 if (!bsem->valid ())
00450 {
00451 rcs_print_error ("CMS: RCS_SEMAPHORE is invalid.\n");
00452 status = CMS_MISC_ERROR;
00453 return -1;
00454 }
00455 #else
00456 char bsem_event_name[80];
00457 #ifndef NO_STDIO
00458 sprintf (bsem_event_name, "event%d", bsem_key);
00459 #else
00460 strcpy (bsem_event_name, "event");
00461 _itoa (bsem_key, bsem_event_name + 5, 10);
00462 #endif
00463 #ifndef UNDER_CE
00464 bsem = OpenEvent (EVENT_ALL_ACCESS, TRUE, bsem_event_name);
00465 #else
00466 #ifdef UNICODE
00467 wchar_t wbsem_event_name[80];
00468 RCS_CE_ASCII_TO_UNICODE (wbsem_event_name, bsem_event_name, 80);
00469 bsem = CreateEvent (NULL, TRUE, FALSE, wbsem_event_name);
00470 #else
00471 bsem = CreateEvent (NULL, TRUE, FALSE, bsem_event_name);
00472 #endif
00473 #endif
00474 if (NULL == bsem)
00475 {
00476 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00477 "OpenEvent error:");
00478 }
00479 #endif
00480 }
00481 }
00482
00483 if (min_compatible_version < 3.44 && min_compatible_version > 0)
00484 {
00485 total_subdivisions = 1;
00486 }
00487
00488 if (min_compatible_version > 2.57 || min_compatible_version <= 0)
00489 {
00490 if (!shm->created)
00491 {
00492 char *cptr = (char *) shm->addr;
00493 cptr[31] = 0;
00494 if (strncmp (cptr, BufferName, 31))
00495 {
00496 rcs_print_error
00497 ("Shared memory buffers %s and %s may conflict. (key=%d(0x%X))\n",
00498 BufferName, cptr, key, key);
00499 strncpy (cptr, BufferName, 32);
00500 }
00501 }
00502 if (master)
00503 {
00504 if (use_autokey_for_connection_number)
00505 {
00506 void *autokey_table_end =
00507 (void *) (((char *) shm->addr) + 32 + autokey_table_size);
00508 memset (autokey_table_end, 0, size - 32 - autokey_table_size);
00509 }
00510 strncpy ((char *) shm->addr, BufferName, 32);
00511 }
00512 if (use_autokey_for_connection_number)
00513 {
00514 void *autokey_table = (void *) (((char *) shm->addr) + 32);
00515 connection_number =
00516 autokey_getkey (autokey_table, total_connections, ProcessName);
00517 shm_addr_offset =
00518 (void *) ((char *) (shm->addr) + 32 + autokey_table_size);
00519 max_message_size -= (32 + autokey_table_size);
00520 }
00521 else
00522 {
00523 shm_addr_offset = (void *) ((char *) (shm->addr) + 32);
00524 max_message_size -= 32;
00525 }
00526
00527 if (enc_max_size <= 0 || enc_max_size > size)
00528 {
00529 if (neutral)
00530 {
00531 max_encoded_message_size -= 32;
00532 }
00533 else
00534 {
00535 max_encoded_message_size -=
00536 (cms_encoded_data_explosion_factor * 32);
00537 }
00538 }
00539
00540 guaranteed_message_space -= 32;
00541
00542 size -= 32;
00543 size_without_diagnostics -= 32;
00544 subdiv_size =
00545 (size_without_diagnostics - total_connections) / total_subdivisions;
00546 subdiv_size -= (subdiv_size % 4);
00547 }
00548 else
00549 {
00550 if (master)
00551 {
00552 memset (shm->addr, 0, size);
00553 }
00554 shm_addr_offset = shm->addr;
00555 }
00556 skip_area = 32 + total_connections + autokey_table_size;
00557 mao.data = shm_addr_offset;
00558 mao.timeout = timeout;
00559 mao.total_connections = total_connections;
00560 mao.sem_delay = sem_delay;
00561 mao.connection_number = connection_number;
00562 mao.split_buffer = split_buffer;
00563 mao.read_only = 0;
00564 mao.sem = sem;
00565
00566 fast_mode = !queuing_enabled && !split_buffer && !neutral &&
00567 (mutex_type == NO_SWITCHING_MUTEX);
00568 handle_to_global_data = dummy_handle = new PHYSMEM_HANDLE;
00569 handle_to_global_data->set_to_ptr (shm_addr_offset, size);
00570 if ((connection_number < 0 || connection_number >= total_connections)
00571 && (mutex_type == MAO_MUTEX || mutex_type == MAO_MUTEX_W_OS_SEM))
00572 {
00573 rcs_print_error ("Bad connection number %d\n", connection_number);
00574 status = CMS_MISC_ERROR;
00575 return -1;
00576 }
00577 return 0;
00578 }
00579
00580
00581 int
00582 SHMEM::close ()
00583 {
00584 int nattch = 0;
00585 second_read = 0;
00586
00587 if (use_autokey_for_connection_number)
00588 {
00589 void *autokey_table = (void *) (((char *) shm->addr) + 32);
00590 autokey_releasekey (autokey_table, total_connections, ProcessName,
00591 connection_number);
00592 }
00593 if (NULL != shm)
00594 {
00595
00596 nattch = shm->nattch ();
00597 shm->delete_totally = delete_totally;
00598 delete shm;
00599 shm = NULL;
00600 }
00601 if (NULL != sem)
00602 {
00603
00604
00605 if (nattch <= 1 || delete_totally)
00606 {
00607 sem->setflag (RCS_SEMAPHORE_CREATE);
00608 }
00609 else
00610 {
00611 sem->setflag (RCS_SEMAPHORE_NOCREATE);
00612 }
00613 delete sem;
00614 }
00615 #ifndef WIN32
00616 if (NULL != bsem)
00617 {
00618
00619
00620 if (nattch <= 1 || delete_totally)
00621 {
00622 bsem->setflag (RCS_SEMAPHORE_CREATE);
00623 }
00624 else
00625 {
00626 bsem->setflag (RCS_SEMAPHORE_NOCREATE);
00627 }
00628 delete bsem;
00629 }
00630 #endif
00631
00632 #ifdef DEBUG
00633 printf ("SHMEM(%s): nattch = %d\n", BufferName, nattch);
00634 #endif
00635
00636 return 0;
00637 }
00638
00639
00640 CMS_STATUS
00641 SHMEM::main_access (void *_local)
00642 {
00643 #if defined(LYNX) && !defined(lynxosPC)
00644 int interrupt_disable_number = 0;
00645 int switching_disable_number = 1;
00646 #endif
00647
00648
00649 if (shm == NULL)
00650 {
00651 second_read = 0;
00652 return (status = CMS_MISC_ERROR);
00653 }
00654
00655 if (bsem == NULL && not_zero (blocking_timeout))
00656 {
00657 rcs_print_error
00658 ("No blocking semaphore available. Can not call blocking_read(%f).\n",
00659 blocking_timeout);
00660 second_read = 0;
00661 return (status = CMS_NO_BLOCKING_SEM_ERROR);
00662 }
00663
00664 mao.read_only = ((internal_access_type == CMS_CHECK_IF_READ_ACCESS) ||
00665 (internal_access_type == CMS_PEEK_ACCESS) ||
00666 (internal_access_type == CMS_READ_ACCESS));
00667
00668 #ifdef VXWORKS
00669 int intLockKey = 0;
00670 #endif
00671
00672 switch (mutex_type)
00673 {
00674 case NO_MUTEX:
00675 break;
00676
00677 case MAO_MUTEX:
00678 case MAO_MUTEX_W_OS_SEM:
00679 switch (mem_get_access (&mao))
00680 {
00681 case -1:
00682 rcs_print_error ("SHMEM: Can't take semaphore\n");
00683 second_read = 0;
00684 return (status = CMS_MISC_ERROR);
00685 case -2:
00686 if (timeout > 0)
00687 {
00688 rcs_print_error ("SHMEM: Timed out waiting for semaphore.\n");
00689 rcs_print_error ("buffer = %s, timeout = %lf sec.\n",
00690 BufferName, timeout);
00691 }
00692 second_read = 0;
00693 return (status = CMS_TIMED_OUT);
00694 default:
00695 break;
00696 }
00697 toggle_bit = mao.toggle_bit;
00698 break;
00699
00700 case OS_SEM_MUTEX:
00701 if (sem == NULL)
00702 {
00703 second_read = 0;
00704 return (status = CMS_MISC_ERROR);
00705 }
00706 switch (sem->wait ())
00707 {
00708 case -1:
00709 rcs_print_error ("SHMEM: Can't take semaphore\n");
00710 second_read = 0;
00711 return (status = CMS_MISC_ERROR);
00712 case -2:
00713 if (timeout > 0)
00714 {
00715 rcs_print_error ("SHMEM: Timed out waiting for semaphore.\n");
00716 rcs_print_error ("buffer = %s, timeout = %lf sec.\n",
00717 BufferName, timeout);
00718 }
00719 second_read = 0;
00720 return (status = CMS_TIMED_OUT);
00721 default:
00722 break;
00723 }
00724 break;
00725
00726 case NO_INTERRUPTS_MUTEX:
00727 #ifdef LYNX
00728 disable (interrupt_disable_number);
00729 break;
00730 #else
00731 #ifdef VXWORKS
00732 intLockKey = intLock ();
00733 break;
00734 #else
00735 rcs_print_error ("Interrupts can not be disabled.\n");
00736 second_read = 0;
00737 return (status = CMS_MISC_ERROR);
00738 break;
00739 #endif
00740 #endif
00741
00742 case NO_SWITCHING_MUTEX:
00743 #ifdef lynxosPC
00744 fa_ptr->preempt++;
00745 break;
00746 #else
00747 #if 0
00748
00749
00750 sdisable (switching_disable_number);
00751 break;
00752 #else
00753 #ifdef VXWORKS
00754 taskLock ();
00755 break;
00756 #else
00757 rcs_print_error ("Interrupts can not be disabled.\n");
00758 return (status = CMS_MISC_ERROR);
00759 break;
00760 #endif
00761 #endif
00762 #endif
00763 default:
00764 rcs_print_error ("SHMEM: Invalid mutex type.(%d)\n", mutex_type);
00765 second_read = 0;
00766 return (status = CMS_MISC_ERROR);
00767 break;
00768 }
00769
00770 if (second_read > 0 && enable_diagnostics)
00771 {
00772 disable_diag_store = 1;
00773 }
00774
00775
00776 internal_access (shm->addr, size, _local);
00777
00778 disable_diag_store = 0;
00779
00780 if (NULL != bsem &&
00781 (internal_access_type == CMS_WRITE_ACCESS
00782 || internal_access_type == CMS_WRITE_IF_READ_ACCESS))
00783 {
00784 #ifndef WIN32
00785 bsem->flush ();
00786 #else
00787 if (!PulseEvent (bsem))
00788 {
00789 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE, "PulseEvent error");
00790 }
00791 #endif
00792 }
00793 switch (mutex_type)
00794 {
00795 case NO_MUTEX:
00796 break;
00797
00798 case MAO_MUTEX:
00799 case MAO_MUTEX_W_OS_SEM:
00800 mem_release_access (&mao);
00801 break;
00802
00803 case OS_SEM_MUTEX:
00804 sem->post ();
00805 break;
00806 case NO_INTERRUPTS_MUTEX:
00807 #ifdef LYNX
00808 restore (interrupt_disable_number);
00809 break;
00810 #else
00811 #ifdef VXWORKS
00812 intUnlock (intLockKey);
00813 #else
00814 rcs_print_error ("Can not restore interrupts.\n");
00815 break;
00816 #endif
00817 #endif
00818
00819 case NO_SWITCHING_MUTEX:
00820 #ifdef lynxosPC
00821 if ((!(--(fa_ptr->preempt)) || fa_ptr->preempt > 0x40) && fa_ptr->flag)
00822 {
00823 fast_enable_preemption ();
00824 }
00825 break;
00826 #else
00827 #if 0
00828
00829
00830 srestore (switching_disable_number);
00831 break;
00832 #else
00833 #ifdef VXWORKS
00834 taskUnlock ();
00835 break;
00836 #else
00837 rcs_print_error ("Can not restore interrupts.\n");
00838 break;
00839 #endif
00840 #endif
00841 #endif
00842 }
00843
00844 switch (internal_access_type)
00845 {
00846
00847 case CMS_READ_ACCESS:
00848 if (NULL != bsem && status == CMS_READ_OLD &&
00849 (blocking_timeout > 1e-6 || blocking_timeout < -1E-6))
00850 {
00851 if (second_read > 10 && total_subdivisions <= 1)
00852 {
00853 status = CMS_MISC_ERROR;
00854 rcs_print_error
00855 ("CMS: Blocking semaphore error. The semaphore wait has returned %d times but there is still no new data.\n",
00856 second_read);
00857 second_read = 0;
00858 return (status);
00859 }
00860 #ifndef WIN32
00861 second_read++;
00862 bsem->timeout = blocking_timeout;
00863 #if !defined(VXWORKS) && !defined(WIN32)
00864 sem_force_fifo = 1;
00865 #endif
00866 int bsem_ret = bsem->wait ();
00867 #if !defined(VXWORKS) && !defined(WIN32)
00868 sem_force_fifo = 0;
00869 #endif
00870 if (bsem_ret == -2)
00871 {
00872 status = CMS_TIMED_OUT;
00873 second_read = 0;
00874 return (status);
00875 }
00876 if (bsem_ret == -1)
00877 {
00878 rcs_print_error ("CMS: Blocking semaphore error.\n");
00879 status = CMS_MISC_ERROR;
00880 second_read = 0;
00881 return (status);
00882 }
00883 #else
00884 DWORD timeoutMillis = (DWORD) (blocking_timeout * 1000.0);
00885 if (blocking_timeout < 0)
00886 {
00887 timeoutMillis = INFINITE;
00888 }
00889 switch (WaitForSingleObject (bsem, timeoutMillis))
00890 {
00891 case WAIT_TIMEOUT:
00892 status = CMS_TIMED_OUT;
00893 second_read = 0;
00894 return (status);
00895
00896 case WAIT_OBJECT_0:
00897 second_read++;
00898 break;
00899
00900 default:
00901 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00902 "WaitForSingleObject error");
00903 status = CMS_MISC_ERROR;
00904 second_read = 0;
00905 return (status);
00906 }
00907 #endif
00908 main_access (_local);
00909 }
00910 break;
00911
00912 case CMS_WRITE_ACCESS:
00913 case CMS_WRITE_IF_READ_ACCESS:
00914 #if 0
00915 if (NULL != bsem)
00916 {
00917 #ifndef WIN32
00918 bsem->flush ();
00919 #else
00920 if (!PulseEvent (bsem))
00921 {
00922 rcs_print_sys_error (GETLASTERROR_ERROR_SOURCE,
00923 "PulseEvent error");
00924 }
00925 #endif
00926 }
00927 #endif
00928 break;
00929
00930 default:
00931 break;
00932
00933 }
00934
00935 second_read = 0;
00936 return (status);
00937 }
00938
00939
00940 #ifdef VXWORKS
00941 CMS_STATUS
00942 SHMEM::read ()
00943 {
00944 if (fast_mode)
00945 {
00946 handle_to_global_data->offset = total_connections;
00947 taskLock ();
00948 read_raw ();
00949 taskUnlock ();
00950 return (status);
00951 }
00952 internal_access_type = CMS_READ_ACCESS;
00953 main_access (data);
00954 return (status);
00955 }
00956
00957 CMS_STATUS
00958 SHMEM::peek ()
00959 {
00960 if (fast_mode)
00961 {
00962 handle_to_global_data->offset = total_connections;
00963 taskLock ();
00964 peek_raw ();
00965 taskUnlock ();
00966 return (status);
00967 }
00968 internal_access_type = CMS_PEEK_ACCESS;
00969 main_access (data);
00970 return (status);
00971 }
00972
00973 CMS_STATUS
00974 SHMEM::write (void *user_data)
00975 {
00976 if (fast_mode)
00977 {
00978 handle_to_global_data->offset = total_connections;
00979 taskLock ();
00980 write_raw (user_data);
00981 taskUnlock ();
00982 return (status);
00983 }
00984 internal_access_type = CMS_WRITE_ACCESS;
00985 main_access (user_data);
00986 return (status);
00987 }
00988
00989 CMS_STATUS
00990 SHMEM::write_if_read (void *user_data)
00991 {
00992 if (fast_mode)
00993 {
00994 handle_to_global_data->offset = total_connections;
00995 taskLock ();
00996 write_if_read_raw (user_data);
00997 taskUnlock ();
00998 return (status);
00999 }
01000 internal_access_type = CMS_WRITE_IF_READ_ACCESS;
01001 main_access (user_data);
01002 return (status);
01003 }
01004 #endif
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018 #if 0
01019
01020 char *internal_access_buffer;
01021 long internal_access_buffer_size;
01022
01023
01024 if (split_buffer)
01025 {
01026 if (internal_access_type == CMS_WRITE_IF_READ_ACCESS)
01027 {
01028 was_read_byte = *(((char *) shm_addr_offset) + total_connections + 1);
01029 header.was_read = (was_read_byte == mao.toggle_bit + 1);
01030 if (!header.was_read)
01031 {
01032 mem_release_access (&mao);
01033 second_read = 0;
01034 return (status = CMS_WRITE_WAS_BLOCKED);
01035 }
01036 internal_access_type = CMS_WRITE_ACCESS;
01037 }
01038 if (mao.read_only == mao.toggle_bit)
01039 {
01040 internal_access_buffer =
01041 ((char *) shm_addr_offset) + total_connections + 2;
01042 internal_access_buffer_size = (size / 2) - total_connections - 2;
01043 }
01044 else
01045 {
01046 internal_access_buffer = ((char *) shm_addr_offset) + (size / 2);
01047 internal_access_buffer_size = (size / 2);
01048 }
01049 }
01050 else
01051 {
01052 int cur_offset = total_connections;
01053 internal_access_buffer_size = (size) - total_connections;
01054 if (total_subdivisions > 0)
01055 {
01056 cur_offset = total_connections + current_subdivision * subdiv_size;
01057 internal_access_buffer_size = subdiv_size;
01058 }
01059 internal_access_buffer = ((char *) shm_addr_offset) + cur_offset;
01060
01061 }
01062
01063 internal_access (internal_access_buffer, internal_access_buffer_size, _local);
01064
01065 if (split_buffer && internal_access_type == CMS_READ_ACCESS)
01066 {
01067 *(((char *) shm_addr_offset) + total_connections + 1) =
01068 mao.toggle_bit + 1;
01069 }
01070 #endif