Main Page   Class Hierarchy   Alphabetical List   Data Structures   File List   Data Fields   Globals  

TCPMEM Class Reference

#include <tcpmem.hh>

Inheritance diagram for TCPMEM:

Inheritance graph
[legend]
Collaboration diagram for TCPMEM:

Collaboration graph
[legend]

Public Methods

 TCPMEM (char *bufline, char *procline)
virtual ~TCPMEM ()
CMS_STATUS clear ()
int check_if_read ()
CMS_STATUS read ()
CMS_STATUS blocking_read (double)
CMS_STATUS peek ()
CMS_STATUS write (void *data)
CMS_STATUS write_if_read (void *data)
int login (const char *, const char *)
void reconnect ()
void disconnect ()
CMS_DIAGNOSTICS_INFOget_diagnostics_info ()

Protected Methods

CMS_STATUS handle_old_replies ()
void send_diag_info ()
void set_socket_fds (int new_fd)
void disable_sigpipe ()
void reenable_sigpipe ()
void verify_bufname ()

Protected Attributes

char diag_info_buf [0x400]
int recvd_bytes
long serial_number
long returned_serial_number
int subscription_type
int poll_interval_millis
hostentserver_host_entry
sockaddr_in server_socket_address
int socket_fd
char temp_buffer [0x2000]
REMOTE_CMS_REQUEST_TYPE timedout_request
long bytes_to_throw_away
int polling
int write_socket_fd
int read_socket_fd
long write_serial_number
long read_serial_number
CMS_STATUS timedout_request_status
unsigned long timedout_request_writeid
int max_consecutive_timeouts
int waiting_for_message
unsigned long waiting_message_size
unsigned long waiting_message_id
int autoreconnect
int reconnect_needed
int sigpipe_count
void(* old_handler )(int)
int subscription_count

Constructor & Destructor Documentation

TCPMEM::TCPMEM char *    _bufline,
char *    _procline
 

Definition at line 69 of file tcpmem.cc.

00069                                               :
00070 CMS (_bufline, _procline)
00071 {
00072 #if defined(_Windows) && !defined(USE_PCNFS)
00073   WSA_count++;
00074 #endif
00075   if (load_socket_interface () < 0)
00076     {
00077       rcs_print_error ("Can't load socket interface.\n");
00078       status = CMS_LIBRARY_UNAVAILABLE_ERROR;
00079     }
00080   max_consecutive_timeouts = DEFAULT_MAX_CONSECUTIVE_TIMEOUTS;
00081   char *max_consecutive_timeouts_string;
00082   max_consecutive_timeouts_string = strstr (ProcessLine, "max_timeouts=");
00083   polling = (NULL != strstr (proclineupper, "POLL"));
00084   socket_fd = 0;
00085   reconnect_needed = 0;
00086   autoreconnect = 1;
00087 #ifndef UNDER_CE
00088   old_handler = (void (*)(int)) SIG_ERR;
00089 #endif
00090   sigpipe_count = 0;
00091   subscription_count = 0;
00092   read_serial_number = 0;
00093   write_serial_number = 0;
00094   read_socket_fd = 0;
00095   write_socket_fd = 0;
00096   if (NULL != max_consecutive_timeouts_string)
00097     {
00098       max_consecutive_timeouts_string += strlen ("max_timeouts=");
00099       if (!strncmp (max_consecutive_timeouts_string, "INF", 3))
00100         {
00101           max_consecutive_timeouts = -1;
00102         }
00103       else
00104         {
00105 #ifndef UNDER_CE
00106           max_consecutive_timeouts =
00107             strtol (max_consecutive_timeouts_string, (char **) NULL, 0);
00108 #else
00109           max_consecutive_timeouts = atol (max_consecutive_timeouts_string);
00110 #endif
00111         }
00112     }
00113 
00114   char *sub_info_string = NULL;
00115   poll_interval_millis = 30000;
00116   subscription_type = CMS_NO_SUBSCRIPTION;
00117   sub_info_string = strstr (ProcessLine, "sub=");
00118   if (NULL != sub_info_string)
00119     {
00120       if (!strncmp (sub_info_string + 4, "none", 4))
00121         {
00122           subscription_type = CMS_NO_SUBSCRIPTION;
00123         }
00124       else if (!strncmp (sub_info_string + 4, "var", 3))
00125         {
00126           subscription_type = CMS_VARIABLE_SUBSCRIPTION;
00127         }
00128       else
00129         {
00130 #ifndef UNDER_CE
00131           poll_interval_millis =
00132             ((int) (atof (sub_info_string + 4) * 1000.0));
00133 #else
00134           poll_interval_millis =
00135             ((int) (RCS_CE_ATOF (sub_info_string + 4) * 1000.0));
00136 #endif
00137           subscription_type = CMS_POLLED_SUBSCRIPTION;
00138         }
00139     }
00140   if (NULL != strstr (ProcessLine, "noreconnect"))
00141     {
00142       autoreconnect = 0;
00143     }
00144 
00145 #ifndef VXWORKS
00146   server_host_entry = NULL;
00147 #endif
00148 
00149   /* Set up the socket address stucture. */
00150   memset (&server_socket_address, 0, sizeof (server_socket_address));
00151   server_socket_address.sin_family = AF_INET;
00152   server_socket_address.sin_port = dl_htons (((u_short) tcp_port_number));
00153   int hostname_was_address = 0;
00154   char bufferhost_first_char = BufferHost[0];
00155   if (bufferhost_first_char >= '0' && bufferhost_first_char <= '9')
00156     {
00157       server_socket_address.sin_addr.s_addr = dl_inet_addr (BufferHost);
00158       if (server_socket_address.sin_addr.s_addr != 0 &&
00159           ((long) server_socket_address.sin_addr.s_addr) != -1)
00160         {
00161           hostname_was_address = 1;
00162         }
00163     }
00164 
00165   if (!hostname_was_address)
00166     {
00167       /* Get the IP address of the server using it's BufferHost. */
00168 #ifndef VXWORKS
00169       dl_gethostbyname (BufferHost, &server_host_entry);
00170       if (NULL == server_host_entry)
00171         {
00172           status = CMS_CONFIG_ERROR;
00173           autoreconnect = 0;
00174 #if defined(_WINDOWS) && !defined(gnuwin32)
00175           rcs_print_sys_error (WSAGETLASTERROR_ERROR_SOURCE,
00176                                "gethostbyname error");
00177 #endif
00178           rcs_print_error ("TCPMEM: Couldn't get host address for (%s).\n",
00179                            BufferHost);
00180           return;
00181         }
00182 #ifdef __MSDOS__
00183       server_socket_address.sin_addr.s_addr =
00184         *((u_long *) server_host_entry->h_addr_list[0]);
00185 #else
00186       server_socket_address.sin_addr.s_addr =
00187         *((int *) server_host_entry->h_addr_list[0]);
00188 #endif
00189       server_socket_address.sin_family = server_host_entry->h_addrtype;
00190 #else
00191       server_socket_address.sin_addr.s_addr = hostGetByName (BufferHost);
00192       if (server_socket_address.sin_addr.s_addr == ERROR)
00193         {
00194           autoreconnect = 0;
00195           rcs_print_error ("TCPMEM: Couldn't get host address for (%s).\n",
00196                            BufferHost);
00197           status = CMS_CONFIG_ERROR;
00198           return;
00199         }
00200 #endif
00201     }
00202   rcs_print_debug (PRINT_CMS_CONFIG_INFO,
00203                    "Using server on %s with IP address %s and port %d.\n",
00204                    BufferHost,
00205                    dl_inet_ntoa (server_socket_address.sin_addr),
00206                    tcp_port_number);
00207 
00208 
00209   reconnect ();
00210 
00211   if (status >= 0 &&
00212       (min_compatible_version > 2.58 || min_compatible_version < 1e-6))
00213     {
00214       verify_bufname ();
00215       if (status < 0)
00216         {
00217           rcs_print_error ("TCPMEM: verify_bufname() failed.\n");
00218         }
00219     }
00220 
00221   if (status >= 0 && enable_diagnostics &&
00222       (min_compatible_version > 3.71 || min_compatible_version < 1e-6))
00223     {
00224       send_diag_info ();
00225     }
00226 }

TCPMEM::~TCPMEM   [virtual]
 

Definition at line 844 of file tcpmem.cc.

00845 {
00846   disconnect ();
00847 
00848 #if defined(_Windows) && !defined(USE_PCNFS)
00849   if (WSA_count == 0)
00850     {
00851       unload_socket_interface ();
00852     }
00853   WSA_count--;
00854 #endif
00855 
00856 }


Member Function Documentation

CMS_STATUS TCPMEM::clear   [virtual]
 

Reimplemented from CMS.

Definition at line 2254 of file tcpmem.cc.

02255 {
02256   if (reconnect_needed && autoreconnect)
02257     {
02258       reconnect ();
02259     }
02260 
02261   if (reconnect_needed)
02262     {
02263       return (status = CMS_MISC_ERROR);
02264     }
02265 
02266   if (fatal_error_occurred)
02267     {
02268       if (status >= 0)
02269         {
02270           status = CMS_MISC_ERROR;
02271         }
02272       return (status);
02273     }
02274   if (socket_fd <= 0)
02275     {
02276       rcs_print_error ("TCPMEM::clear: Invalid socket descriptor. (%d)\n",
02277                        socket_fd);
02278       reconnect_needed = 1;
02279       return (status = CMS_MISC_ERROR);
02280     }
02281   if (((int) handle_old_replies ()) < 0)
02282     {
02283       return status;
02284     }
02285 
02286   set_socket_fds (write_socket_fd);
02287 
02288   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
02289   *((u_long *) temp_buffer + 1) =
02290     dl_htonl ((u_long) REMOTE_CMS_CLEAR_REQUEST_TYPE);
02291   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
02292   *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) current_subdivision);
02293 
02294   if (sendn (socket_fd, temp_buffer, 20, 0, timeout) < 0)
02295     {
02296       reconnect_needed = 1;
02297       return (status = CMS_MISC_ERROR);
02298     }
02299   serial_number++;
02300   if (recvn (socket_fd, temp_buffer, 8, 0, timeout, &recvd_bytes) < 0)
02301     {
02302       if (recvn_timedout)
02303         {
02304           timedout_request = REMOTE_CMS_CLEAR_REQUEST_TYPE;
02305           consecutive_timeouts = 1;
02306           return (status = CMS_TIMED_OUT);
02307         }
02308       else
02309         {
02310           fatal_error_occurred = 1;
02311           reconnect_needed = 1;
02312           return (status = CMS_MISC_ERROR);
02313         }
02314     }
02315   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
02316   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
02317                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
02318                    socket_fd, returned_serial_number, buffer_number);
02319 
02320   if (returned_serial_number != serial_number)
02321     {
02322       rcs_print_error
02323         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
02324          returned_serial_number, serial_number);
02325       reconnect_needed = 1;
02326       return (status = CMS_MISC_ERROR);
02327     }
02328   status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
02329   header.was_read = dl_ntohl (*((u_long *) temp_buffer + 2));
02330   return (status);
02331 }

int TCPMEM::check_if_read   [virtual]
 

Reimplemented from CMS.

Definition at line 2158 of file tcpmem.cc.

02159 {
02160   if (reconnect_needed && autoreconnect)
02161     {
02162       reconnect ();
02163     }
02164 
02165   if (reconnect_needed)
02166     {
02167       return (status = CMS_MISC_ERROR);
02168     }
02169 
02170   if (fatal_error_occurred)
02171     {
02172       if (status >= 0)
02173         {
02174           status = CMS_MISC_ERROR;
02175         }
02176       return (status);
02177     }
02178 
02179   disable_sigpipe ();
02180 
02181   if (socket_fd <= 0)
02182     {
02183       rcs_print_error
02184         ("TCPMEM::check_if_read: Invalid socket descriptor. (%d)\n",
02185          socket_fd);
02186       reenable_sigpipe ();
02187       return (status = CMS_MISC_ERROR);
02188     }
02189   if (((int) handle_old_replies ()) < 0)
02190     {
02191       reenable_sigpipe ();
02192       return 0;
02193     }
02194 
02195   set_socket_fds (write_socket_fd);
02196 
02197   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
02198   *((u_long *) temp_buffer + 1) =
02199     dl_htonl ((u_long) REMOTE_CMS_CHECK_IF_READ_REQUEST_TYPE);
02200   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
02201   int send_header_size = 20;
02202   if (total_subdivisions > 1)
02203     {
02204       *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) current_subdivision);
02205     }
02206   if (sendn (socket_fd, temp_buffer, send_header_size, 0, timeout) < 0)
02207     {
02208       status = CMS_MISC_ERROR;
02209       reconnect_needed = 1;
02210       reenable_sigpipe ();
02211       return (0);
02212     }
02213   serial_number++;
02214   if (recvn (socket_fd, temp_buffer, 12, 0, timeout, &recvd_bytes) < 0)
02215     {
02216       if (recvn_timedout)
02217         {
02218           timedout_request = REMOTE_CMS_CHECK_IF_READ_REQUEST_TYPE;
02219           consecutive_timeouts = 1;
02220           status = CMS_TIMED_OUT;
02221           reenable_sigpipe ();
02222           return 0;
02223         }
02224       else
02225         {
02226           recvd_bytes = 0;
02227           fatal_error_occurred = 1;
02228           status = CMS_MISC_ERROR;
02229           reenable_sigpipe ();
02230           return 0;
02231         }
02232     }
02233   recvd_bytes = 0;
02234   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
02235   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
02236                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
02237                    socket_fd, returned_serial_number, buffer_number);
02238   if (returned_serial_number != serial_number)
02239     {
02240       rcs_print_error
02241         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
02242          returned_serial_number, serial_number);
02243       reenable_sigpipe ();
02244       return (status = CMS_MISC_ERROR);
02245     }
02246   status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
02247   header.was_read = dl_ntohl (*((u_long *) temp_buffer + 2));
02248   reenable_sigpipe ();
02249   return (header.was_read);
02250 }

CMS_STATUS TCPMEM::read   [virtual]
 

Reimplemented from CMS.

Definition at line 1172 of file tcpmem.cc.

01173 {
01174   long message_size, id;
01175   REMOTE_CMS_REQUEST_TYPE last_timedout_request;
01176 
01177   /* Produce error message if process does not have permission to read. */
01178   if (!read_permission_flag)
01179     {
01180       rcs_print_error ("CMS: %s was not configured to read %s\n",
01181                        ProcessName, BufferName);
01182       return (status = CMS_PERMISSIONS_ERROR);
01183     }
01184 
01185   if (reconnect_needed && autoreconnect)
01186     {
01187       reconnect ();
01188     }
01189 
01190   if (reconnect_needed)
01191     {
01192       return (status = CMS_MISC_ERROR);
01193     }
01194   disable_sigpipe ();
01195 
01196   if (subscription_type != CMS_NO_SUBSCRIPTION)
01197     {
01198       set_socket_fds (read_socket_fd);
01199       timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01200       if (subscription_count < 1)
01201         {
01202           serial_number++;
01203         }
01204       handle_old_replies ();
01205       check_id (timedout_request_writeid);
01206       if (status == CMS_READ_OK)
01207         {
01208           serial_number++;
01209         }
01210       subscription_count++;
01211       reenable_sigpipe ();
01212       return status;
01213     }
01214 
01215   if (timedout_request == NO_REMOTE_CMS_REQUEST)
01216     {
01217       set_socket_fds (read_socket_fd);
01218     }
01219   if (fatal_error_occurred)
01220     {
01221       if (status >= 0)
01222         {
01223           status = CMS_MISC_ERROR;
01224         }
01225       reenable_sigpipe ();
01226       return (status);
01227     }
01228   if (socket_fd <= 0)
01229     {
01230       rcs_print_error ("TCPMEM::read: Invalid socket descriptor. (%d)\n",
01231                        socket_fd);
01232       fatal_error_occurred = 1;
01233       reconnect_needed = 1;
01234       reenable_sigpipe ();
01235       return (status = CMS_MISC_ERROR);
01236     }
01237   last_timedout_request = timedout_request;
01238   if (((int) handle_old_replies ()) < 0)
01239     {
01240       reenable_sigpipe ();
01241       return status;
01242     }
01243   if (polling && last_timedout_request == REMOTE_CMS_READ_REQUEST_TYPE)
01244     {
01245       check_id (timedout_request_writeid);
01246       reenable_sigpipe ();
01247       return status;
01248     }
01249   set_socket_fds (read_socket_fd);
01250 
01251   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
01252   *((u_long *) temp_buffer + 1) =
01253     dl_htonl ((u_long) REMOTE_CMS_READ_REQUEST_TYPE);
01254   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
01255   *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) CMS_READ_ACCESS);
01256   *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) in_buffer_id);
01257 
01258   int send_header_size = 20;
01259   if (total_subdivisions > 1)
01260     {
01261       *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) current_subdivision);
01262       send_header_size = 24;
01263     }
01264   if (sendn (socket_fd, temp_buffer, send_header_size, 0, timeout) < 0)
01265     {
01266       rcs_print_error ("TCPMEM: Can't send READ request to server.\n");
01267       reconnect_needed = 1;
01268       fatal_error_occurred = 1;
01269       reenable_sigpipe ();
01270       return (status = CMS_MISC_ERROR);
01271     }
01272   serial_number++;
01273   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
01274                    "TCPMEM sending request: fd = %d, serial_number=%d, request_type=%d, buffer_number=%d\n",
01275                    socket_fd, serial_number,
01276                    dl_ntohl (*((u_long *) temp_buffer + 1)), buffer_number);
01277 
01278   if (recvn (socket_fd, temp_buffer, 20, 0, timeout, &recvd_bytes) < 20)
01279     {
01280       if (recvn_timedout)
01281         {
01282           timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01283           if (polling)
01284             {
01285               return (status = CMS_READ_OLD);
01286             }
01287           else
01288             {
01289               consecutive_timeouts = 1;
01290               reenable_sigpipe ();
01291               return (status = CMS_TIMED_OUT);
01292             }
01293         }
01294       else
01295         {
01296           recvd_bytes = 0;
01297           reconnect_needed = 1;
01298           fatal_error_occurred = 1;
01299           reenable_sigpipe ();
01300           return (status = CMS_MISC_ERROR);
01301         }
01302     }
01303   recvd_bytes = 0;
01304   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
01305   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
01306                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
01307                    socket_fd, returned_serial_number, buffer_number);
01308 
01309   if (returned_serial_number != serial_number)
01310     {
01311       rcs_print_error
01312         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
01313          returned_serial_number, serial_number);
01314       reconnect_needed = 1;
01315       if (subscription_type == CMS_NO_SUBSCRIPTION)
01316         {
01317           fatal_error_occurred = 1;
01318           reenable_sigpipe ();
01319           return (status = CMS_MISC_ERROR);
01320         }
01321     }
01322   status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
01323   message_size = dl_ntohl (*((u_long *) temp_buffer + 2));
01324   id = dl_ntohl (*((u_long *) temp_buffer + 3));
01325   header.was_read = dl_ntohl (*((u_long *) temp_buffer + 4));
01326   if (message_size > max_encoded_message_size)
01327     {
01328       rcs_print_error ("Recieved message is too big. (%ld > %ld)\n",
01329                        message_size, max_encoded_message_size);
01330       fatal_error_occurred = 1;
01331       reconnect_needed = 1;
01332       reenable_sigpipe ();
01333       return (status = CMS_MISC_ERROR);
01334     }
01335   if (message_size > 0)
01336     {
01337       if (recvn
01338           (socket_fd, encoded_data, message_size, 0, timeout,
01339            &recvd_bytes) < 0)
01340         {
01341           if (recvn_timedout)
01342             {
01343               if (!waiting_for_message)
01344                 {
01345                   waiting_message_id = id;
01346                   waiting_message_size = message_size;
01347                 }
01348               waiting_for_message = 1;
01349               timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01350               if (polling)
01351                 {
01352                   reenable_sigpipe ();
01353                   return (status = CMS_READ_OLD);
01354                 }
01355               else
01356                 {
01357                   reenable_sigpipe ();
01358                   return (status = CMS_TIMED_OUT);
01359                 }
01360             }
01361           else
01362             {
01363               recvd_bytes = 0;
01364               fatal_error_occurred = 1;
01365               reconnect_needed = 1;
01366               reenable_sigpipe ();
01367               return (status = CMS_MISC_ERROR);
01368             }
01369         }
01370     }
01371   recvd_bytes = 0;
01372   check_id (id);
01373   reenable_sigpipe ();
01374   return (status);
01375 }

CMS_STATUS TCPMEM::blocking_read double    _blocking_timeout [virtual]
 

Reimplemented from CMS.

Definition at line 1379 of file tcpmem.cc.

01380 {
01381   blocking_timeout = _blocking_timeout;
01382   long message_size, id;
01383   REMOTE_CMS_REQUEST_TYPE last_timedout_request;
01384   long timeout_millis;
01385   int orig_print_recvn_timeout_errors = print_recvn_timeout_errors;
01386   print_recvn_timeout_errors = 0;
01387 
01388 /* Produce error message if process does not have permission to read. */
01389   if (!read_permission_flag)
01390     {
01391       rcs_print_error ("CMS: %s was not configured to read %s\n",
01392                        ProcessName, BufferName);
01393       return (status = CMS_PERMISSIONS_ERROR);
01394     }
01395 
01396   if (blocking_timeout < 0)
01397     {
01398       timeout_millis = -1;
01399     }
01400   else
01401     {
01402       timeout_millis = (u_long) (blocking_timeout * 1000.0);
01403     }
01404 
01405   if (reconnect_needed && autoreconnect)
01406     {
01407       reconnect ();
01408     }
01409 
01410   if (reconnect_needed)
01411     {
01412       print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01413       return (status = CMS_MISC_ERROR);
01414     }
01415   disable_sigpipe ();
01416   double orig_timeout = timeout;
01417 
01418   if (subscription_type != CMS_NO_SUBSCRIPTION)
01419     {
01420       if (blocking_timeout < -1e-6 || blocking_timeout > 1e-6)
01421         {
01422           make_tcp_socket_blocking (read_socket_fd);
01423           timeout = blocking_timeout;
01424         }
01425       set_socket_fds (read_socket_fd);
01426       if (subscription_count < 1)
01427         {
01428           serial_number++;
01429         }
01430       timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01431       handle_old_replies ();
01432       check_id (timedout_request_writeid);
01433       if (status == CMS_READ_OK)
01434         {
01435           serial_number++;
01436         }
01437       subscription_count++;
01438       reenable_sigpipe ();
01439       if (blocking_timeout < -1e-6 || blocking_timeout > 1e-6)
01440         {
01441           make_tcp_socket_nonblocking (read_socket_fd);
01442           timeout = orig_timeout;
01443         }
01444       print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01445       return status;
01446     }
01447 
01448   if (timedout_request == NO_REMOTE_CMS_REQUEST)
01449     {
01450       set_socket_fds (read_socket_fd);
01451     }
01452   if (fatal_error_occurred)
01453     {
01454       if (status >= 0)
01455         {
01456           status = CMS_MISC_ERROR;
01457         }
01458       reenable_sigpipe ();
01459       print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01460       return (status);
01461     }
01462   if (socket_fd <= 0)
01463     {
01464       rcs_print_error ("TCPMEM::read: Invalid socket descriptor. (%d)\n",
01465                        socket_fd);
01466       fatal_error_occurred = 1;
01467       reconnect_needed = 1;
01468       reenable_sigpipe ();
01469       print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01470       return (status = CMS_MISC_ERROR);
01471     }
01472   last_timedout_request = timedout_request;
01473   if (((int) handle_old_replies ()) < 0)
01474     {
01475       reenable_sigpipe ();
01476       print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01477       return status;
01478     }
01479   if (polling && last_timedout_request == REMOTE_CMS_READ_REQUEST_TYPE)
01480     {
01481       check_id (timedout_request_writeid);
01482       reenable_sigpipe ();
01483       print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01484       return status;
01485     }
01486   set_socket_fds (read_socket_fd);
01487 
01488   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
01489   *((u_long *) temp_buffer + 1) =
01490     dl_htonl ((u_long) REMOTE_CMS_BLOCKING_READ_REQUEST_TYPE);
01491   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
01492   *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) CMS_READ_ACCESS);
01493   *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) in_buffer_id);
01494   *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) timeout_millis);
01495 
01496   int send_header_size = 24;
01497   if (total_subdivisions > 1)
01498     {
01499       *((u_long *) temp_buffer + 6) = dl_htonl ((u_long) current_subdivision);
01500       send_header_size = 28;
01501     }
01502   if (sendn (socket_fd, temp_buffer, send_header_size, 0, blocking_timeout) <
01503       0)
01504     {
01505       rcs_print_error
01506         ("TCPMEM: Can't send BLOCKING_READ request to server.\n");
01507       reconnect_needed = 1;
01508       fatal_error_occurred = 1;
01509       reenable_sigpipe ();
01510       print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01511       return (status = CMS_MISC_ERROR);
01512     }
01513   serial_number++;
01514   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
01515                    "TCPMEM sending request: fd = %d, serial_number=%d, "
01516                    "request_type=%d, buffer_number=%d\n",
01517                    socket_fd, serial_number,
01518                    dl_ntohl (*((u_long *) temp_buffer + 1)), buffer_number);
01519   if (recvn (socket_fd, temp_buffer, 20, 0, blocking_timeout, &recvd_bytes) <
01520       0)
01521     {
01522       print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01523       if (recvn_timedout)
01524         {
01525           timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01526           if (polling)
01527             {
01528               return (status = CMS_READ_OLD);
01529             }
01530           else
01531             {
01532               consecutive_timeouts = 1;
01533               reenable_sigpipe ();
01534               return (status = CMS_TIMED_OUT);
01535             }
01536         }
01537       else
01538         {
01539           recvd_bytes = 0;
01540           reconnect_needed = 1;
01541           fatal_error_occurred = 1;
01542           reenable_sigpipe ();
01543           return (status = CMS_MISC_ERROR);
01544         }
01545     }
01546   print_recvn_timeout_errors = orig_print_recvn_timeout_errors;
01547   recvd_bytes = 0;
01548   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
01549   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
01550                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
01551                    socket_fd, returned_serial_number, buffer_number);
01552 
01553   if (returned_serial_number != serial_number)
01554     {
01555       rcs_print_error
01556         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
01557          returned_serial_number, serial_number);
01558       reconnect_needed = 1;
01559       if (subscription_type == CMS_NO_SUBSCRIPTION)
01560         {
01561           fatal_error_occurred = 1;
01562           reenable_sigpipe ();
01563           return (status = CMS_MISC_ERROR);
01564         }
01565     }
01566   status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
01567   message_size = dl_ntohl (*((u_long *) temp_buffer + 2));
01568   id = dl_ntohl (*((u_long *) temp_buffer + 3));
01569   header.was_read = dl_ntohl (*((u_long *) temp_buffer + 4));
01570   if (message_size > max_encoded_message_size)
01571     {
01572       rcs_print_error ("Recieved message is too big. (%ld > %ld)\n",
01573                        message_size, max_encoded_message_size);
01574       fatal_error_occurred = 1;
01575       reconnect_needed = 1;
01576       reenable_sigpipe ();
01577       return (status = CMS_MISC_ERROR);
01578     }
01579   if (message_size > 0)
01580     {
01581       if (recvn
01582           (socket_fd, encoded_data, message_size, 0, blocking_timeout,
01583            &recvd_bytes) < 0)
01584         {
01585           if (recvn_timedout)
01586             {
01587               if (!waiting_for_message)
01588                 {
01589                   waiting_message_id = id;
01590                   waiting_message_size = message_size;
01591                 }
01592               waiting_for_message = 1;
01593               timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01594               if (polling)
01595                 {
01596                   reenable_sigpipe ();
01597                   return (status = CMS_READ_OLD);
01598                 }
01599               else
01600                 {
01601                   reenable_sigpipe ();
01602                   return (status = CMS_TIMED_OUT);
01603                 }
01604             }
01605           else
01606             {
01607               recvd_bytes = 0;
01608               fatal_error_occurred = 1;
01609               reconnect_needed = 1;
01610               reenable_sigpipe ();
01611               return (status = CMS_MISC_ERROR);
01612             }
01613         }
01614     }
01615   recvd_bytes = 0;
01616   check_id (id);
01617   reenable_sigpipe ();
01618   return (status);
01619 }

CMS_STATUS TCPMEM::peek   [virtual]
 

Reimplemented from CMS.

Definition at line 1656 of file tcpmem.cc.

01657 {
01658   /* Produce error message if process does not have permission to read. */
01659   if (!read_permission_flag)
01660     {
01661       rcs_print_error ("CMS: %s was not configured to read %s\n",
01662                        ProcessName, BufferName);
01663       return (status = CMS_PERMISSIONS_ERROR);
01664     }
01665 
01666   if (reconnect_needed && autoreconnect)
01667     {
01668       reconnect ();
01669     }
01670 
01671   if (reconnect_needed)
01672     {
01673       return (status = CMS_MISC_ERROR);
01674     }
01675   disable_sigpipe ();
01676 
01677   long message_size, id;
01678   REMOTE_CMS_REQUEST_TYPE last_timedout_request;
01679   if (subscription_type != CMS_NO_SUBSCRIPTION)
01680     {
01681       set_socket_fds (read_socket_fd);
01682       timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01683       if (subscription_count < 1)
01684         {
01685           serial_number++;
01686         }
01687       handle_old_replies ();
01688       check_id (timedout_request_writeid);
01689       if (status == CMS_READ_OK)
01690         {
01691           serial_number++;
01692         }
01693       reenable_sigpipe ();
01694       subscription_count++;
01695       return status;
01696     }
01697 
01698   if (timedout_request == NO_REMOTE_CMS_REQUEST)
01699     {
01700       set_socket_fds (read_socket_fd);
01701     }
01702 
01703   if (fatal_error_occurred)
01704     {
01705       if (status >= 0)
01706         {
01707           status = CMS_MISC_ERROR;
01708         }
01709       reenable_sigpipe ();
01710       return (status);
01711     }
01712   if (socket_fd <= 0)
01713     {
01714       reconnect_needed = 1;
01715       rcs_print_error ("TCPMEM::read: Invalid socket descriptor. (%d)\n",
01716                        socket_fd);
01717       reenable_sigpipe ();
01718       return (status = CMS_MISC_ERROR);
01719     }
01720   last_timedout_request = timedout_request;
01721   if (((int) handle_old_replies ()) < 0)
01722     {
01723       reenable_sigpipe ();
01724       return status;
01725     }
01726   if (polling && last_timedout_request == REMOTE_CMS_READ_REQUEST_TYPE)
01727     {
01728       check_id (timedout_request_writeid);
01729       reenable_sigpipe ();
01730       return status;
01731     }
01732   set_socket_fds (read_socket_fd);
01733 
01734   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
01735   *((u_long *) temp_buffer + 1) =
01736     dl_htonl ((u_long) REMOTE_CMS_READ_REQUEST_TYPE);
01737   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
01738   *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) CMS_PEEK_ACCESS);
01739   *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) in_buffer_id);
01740   int send_header_size = 20;
01741   if (total_subdivisions > 1)
01742     {
01743       *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) current_subdivision);
01744       send_header_size = 24;
01745     }
01746   if (sendn (socket_fd, temp_buffer, send_header_size, 0, timeout) < 0)
01747     {
01748       rcs_print_error ("TCPMEM: Can't send PEEK request to server.\n");
01749       reconnect_needed = 1;
01750       reenable_sigpipe ();
01751       return (status = CMS_MISC_ERROR);
01752     }
01753   serial_number++;
01754   if (recvn (socket_fd, temp_buffer, 20, 0, timeout, &recvd_bytes) < 0)
01755     {
01756       if (recvn_timedout)
01757         {
01758           timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01759           if (polling)
01760             {
01761               reenable_sigpipe ();
01762               return (status = CMS_READ_OLD);
01763             }
01764           else
01765             {
01766               consecutive_timeouts = 1;
01767               reenable_sigpipe ();
01768               return (status = CMS_TIMED_OUT);
01769             }
01770         }
01771       else
01772         {
01773           recvd_bytes = 0;
01774           fatal_error_occurred = 1;
01775           reconnect_needed = 1;
01776           reenable_sigpipe ();
01777           return (status = CMS_MISC_ERROR);
01778         }
01779     }
01780   recvd_bytes = 0;
01781   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
01782   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
01783                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
01784                    socket_fd, returned_serial_number, buffer_number);
01785 
01786   if (returned_serial_number != serial_number)
01787     {
01788       rcs_print_error
01789         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
01790          returned_serial_number, serial_number);
01791       reconnect_needed = 1;
01792       if (subscription_type == CMS_NO_SUBSCRIPTION)
01793         {
01794           reenable_sigpipe ();
01795           return (status = CMS_MISC_ERROR);
01796         }
01797     }
01798   status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
01799   message_size = dl_ntohl (*((u_long *) temp_buffer + 2));
01800   id = dl_ntohl (*((u_long *) temp_buffer + 3));
01801   header.was_read = dl_ntohl (*((u_long *) temp_buffer + 4));
01802   if (message_size > max_encoded_message_size)
01803     {
01804       reconnect_needed = 1;
01805       rcs_print_error ("Recieved message is too big. (%ld > %ld)\n",
01806                        message_size, max_encoded_message_size);
01807       reenable_sigpipe ();
01808       return (status = CMS_MISC_ERROR);
01809     }
01810   if (message_size > 0)
01811     {
01812       if (recvn
01813           (socket_fd, encoded_data, message_size, 0, timeout,
01814            &recvd_bytes) < 0)
01815         {
01816           if (recvn_timedout)
01817             {
01818               if (!waiting_for_message)
01819                 {
01820                   waiting_message_id = id;
01821                   waiting_message_size = message_size;
01822                 }
01823               waiting_for_message = 1;
01824               timedout_request = REMOTE_CMS_READ_REQUEST_TYPE;
01825               if (polling)
01826                 {
01827                   reenable_sigpipe ();
01828                   return (status = CMS_READ_OLD);
01829                 }
01830               else
01831                 {
01832                   reenable_sigpipe ();
01833                   return (status = CMS_TIMED_OUT);
01834                 }
01835             }
01836           else
01837             {
01838               reconnect_needed = 1;
01839               recvd_bytes = 0;
01840               fatal_error_occurred = 1;
01841               reenable_sigpipe ();
01842               return (status = CMS_MISC_ERROR);
01843             }
01844         }
01845     }
01846   recvd_bytes = 0;
01847   check_id (id);
01848   reenable_sigpipe ();
01849   return (status);
01850 }

CMS_STATUS TCPMEM::write void *    user_data [virtual]
 

Reimplemented from CMS.

Definition at line 1855 of file tcpmem.cc.

01856 {
01857 
01858   if (!write_permission_flag)
01859 
01860     {
01861       rcs_print_error ("CMS: %s was not configured to write to %s\n",
01862                        ProcessName, BufferName);
01863       return (status = CMS_PERMISSIONS_ERROR);
01864     }
01865 
01866   if (reconnect_needed && autoreconnect)
01867     {
01868       reconnect ();
01869     }
01870 
01871   if (!force_raw)
01872     {
01873       user_data = encoded_data;
01874     }
01875 
01876   if (reconnect_needed)
01877     {
01878       return (status = CMS_MISC_ERROR);
01879     }
01880 
01881   if (fatal_error_occurred)
01882     {
01883       if (status >= 0)
01884         {
01885           status = CMS_MISC_ERROR;
01886         }
01887       return (status);
01888     }
01889 
01890   disable_sigpipe ();
01891 
01892   if (socket_fd <= 0)
01893     {
01894       rcs_print_error ("TCPMEM::write: Invalid socket descriptor. (%d)\n",
01895                        socket_fd);
01896       reenable_sigpipe ();
01897       return (status = CMS_MISC_ERROR);
01898     }
01899   if (((int) handle_old_replies ()) < 0)
01900     {
01901       reenable_sigpipe ();
01902       return status;
01903     }
01904   set_socket_fds (write_socket_fd);
01905 
01906 
01907   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
01908   *((u_long *) temp_buffer + 1) =
01909     dl_htonl ((u_long) REMOTE_CMS_WRITE_REQUEST_TYPE);
01910   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
01911   *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) CMS_WRITE_ACCESS);
01912   *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) header.in_buffer_size);
01913   int send_header_size = 20;
01914   if (total_subdivisions > 1)
01915     {
01916       *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) current_subdivision);
01917       send_header_size = 24;
01918     }
01919   if (header.in_buffer_size < 0x2000 - 20 && header.in_buffer_size > 0)
01920     {
01921       memcpy (temp_buffer + send_header_size, user_data,
01922               header.in_buffer_size);
01923       if (sendn
01924           (socket_fd, temp_buffer, header.in_buffer_size + send_header_size,
01925            0, timeout) < 0)
01926         {
01927           rcs_print_error
01928             ("TCPMEM: Failed to send message of size %d + header of size %d  to the server.\n",
01929              header.in_buffer_size, send_header_size);
01930           reconnect_needed = 1;
01931           reenable_sigpipe ();
01932           return (status = CMS_MISC_ERROR);
01933         }
01934     }
01935   else
01936     {
01937       if (sendn (socket_fd, temp_buffer, send_header_size, 0, timeout) < 0)
01938         {
01939           rcs_print_error ("TCPMEM: Failed to send header to server.\n");
01940           reconnect_needed = 1;
01941           reenable_sigpipe ();
01942           return (status = CMS_MISC_ERROR);
01943         }
01944       if (header.in_buffer_size > 0)
01945         {
01946           if (sendn (socket_fd, user_data, header.in_buffer_size, 0, timeout)
01947               < 0)
01948             {
01949               reconnect_needed = 1;
01950               reenable_sigpipe ();
01951               return (status = CMS_MISC_ERROR);
01952             }
01953         }
01954     }
01955   serial_number++;
01956   if ((min_compatible_version < 2.58 && min_compatible_version > 1e-6)
01957       || confirm_write)
01958     {
01959       if (recvn (socket_fd, temp_buffer, 12, 0, timeout, &recvd_bytes) < 0)
01960         {
01961           if (recvn_timedout)
01962             {
01963               timedout_request = REMOTE_CMS_WRITE_REQUEST_TYPE;
01964               consecutive_timeouts = 1;
01965               reenable_sigpipe ();
01966               return (status = CMS_TIMED_OUT);
01967             }
01968           else
01969             {
01970               recvd_bytes = 0;
01971               reconnect_needed = 1;
01972               fatal_error_occurred = 1;
01973               reenable_sigpipe ();
01974               return (status = CMS_MISC_ERROR);
01975             }
01976         }
01977       recvd_bytes = 0;
01978       returned_serial_number =
01979         (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
01980       rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
01981                        "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
01982                        socket_fd, returned_serial_number, buffer_number);
01983 
01984       if (returned_serial_number != serial_number)
01985         {
01986           rcs_print_error
01987             ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
01988              returned_serial_number, serial_number);
01989           reconnect_needed = 1;
01990           if (subscription_type == CMS_NO_SUBSCRIPTION)
01991             {
01992               reenable_sigpipe ();
01993               return (status = CMS_MISC_ERROR);
01994             }
01995         }
01996       status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
01997       header.was_read = dl_ntohl (*((u_long *) temp_buffer + 2));
01998     }
01999   else
02000     {
02001       header.was_read = 0;
02002       status = CMS_WRITE_OK;
02003       returned_serial_number = serial_number;
02004     }
02005   reenable_sigpipe ();
02006   return (status);
02007 }

CMS_STATUS TCPMEM::write_if_read void *    user_data [virtual]
 

Reimplemented from CMS.

Definition at line 2010 of file tcpmem.cc.

02011 {
02012 
02013   if (!write_permission_flag)
02014 
02015     {
02016       rcs_print_error ("CMS: %s was not configured to write to %s\n",
02017                        ProcessName, BufferName);
02018       return (status = CMS_PERMISSIONS_ERROR);
02019     }
02020 
02021   if (reconnect_needed && autoreconnect)
02022     {
02023       reconnect ();
02024     }
02025   if (!force_raw)
02026     {
02027       user_data = encoded_data;
02028     }
02029 
02030   if (reconnect_needed)
02031     {
02032       return (status = CMS_MISC_ERROR);
02033     }
02034 
02035   if (fatal_error_occurred)
02036     {
02037       if (status >= 0)
02038         {
02039           status = CMS_MISC_ERROR;
02040         }
02041       return (status);
02042     }
02043   disable_sigpipe ();
02044 
02045   if (socket_fd <= 0)
02046     {
02047       rcs_print_error ("TCPMEM::write: Invalid socket descriptor. (%d)\n",
02048                        socket_fd);
02049       reenable_sigpipe ();
02050       return (status = CMS_MISC_ERROR);
02051     }
02052   if (((int) handle_old_replies ()) < 0)
02053     {
02054       reenable_sigpipe ();
02055       return status;
02056     }
02057 
02058   set_socket_fds (write_socket_fd);
02059 
02060   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
02061   *((u_long *) temp_buffer + 1) =
02062     dl_htonl ((u_long) REMOTE_CMS_WRITE_REQUEST_TYPE);
02063   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
02064   *((u_long *) temp_buffer + 3) =
02065     dl_htonl ((u_long) CMS_WRITE_IF_READ_ACCESS);
02066   *((u_long *) temp_buffer + 4) = dl_htonl ((u_long) header.in_buffer_size);
02067   int send_header_size = 20;
02068   if (total_subdivisions > 1)
02069     {
02070       *((u_long *) temp_buffer + 5) = dl_htonl ((u_long) current_subdivision);
02071       send_header_size = 24;
02072     }
02073   if (header.in_buffer_size < 0x2000 - 20 && header.in_buffer_size > 0)
02074     {
02075       memcpy (temp_buffer + 20, user_data, header.in_buffer_size);
02076       if (sendn
02077           (socket_fd, temp_buffer, header.in_buffer_size + send_header_size,
02078            0, timeout) < 0)
02079         {
02080           reconnect_needed = 1;
02081           reenable_sigpipe ();
02082           return (status = CMS_MISC_ERROR);
02083         }
02084     }
02085   else
02086     {
02087       if (sendn (socket_fd, temp_buffer, send_header_size, 0, timeout) < 0)
02088         {
02089           reconnect_needed = 1;
02090           reenable_sigpipe ();
02091           return (status = CMS_MISC_ERROR);
02092         }
02093       if (header.in_buffer_size > 0)
02094         {
02095           if (sendn (socket_fd, user_data, header.in_buffer_size, 0, timeout)
02096               < 0)
02097             {
02098               reconnect_needed = 1;
02099               reenable_sigpipe ();
02100               return (status = CMS_MISC_ERROR);
02101             }
02102         }
02103     }
02104   serial_number++;
02105   if ((min_compatible_version < 2.58 && min_compatible_version > 1e-6) ||
02106       confirm_write)
02107     {
02108       if (recvn (socket_fd, temp_buffer, 12, 0, timeout, &recvd_bytes) < 0)
02109         {
02110           if (recvn_timedout)
02111             {
02112               timedout_request = REMOTE_CMS_WRITE_REQUEST_TYPE;
02113               consecutive_timeouts = 1;
02114               reenable_sigpipe ();
02115               return (status = CMS_TIMED_OUT);
02116             }
02117           else
02118             {
02119               recvd_bytes = 0;
02120               fatal_error_occurred = 1;
02121               reconnect_needed = 1;
02122               reenable_sigpipe ();
02123               return (status = CMS_MISC_ERROR);
02124             }
02125         }
02126       recvd_bytes = 0;
02127       returned_serial_number =
02128         (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
02129       rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
02130                        "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
02131                        socket_fd, returned_serial_number, buffer_number);
02132       if (returned_serial_number != serial_number)
02133         {
02134           rcs_print_error
02135             ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
02136              returned_serial_number, serial_number);
02137           reconnect_needed = 1;
02138           if (subscription_type == CMS_NO_SUBSCRIPTION)
02139             {
02140               reenable_sigpipe ();
02141               return (status = CMS_MISC_ERROR);
02142             }
02143         }
02144       status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
02145       header.was_read = dl_ntohl (*((u_long *) temp_buffer + 2));
02146     }
02147   else
02148     {
02149       header.was_read = 0;
02150       status = CMS_WRITE_OK;
02151       returned_serial_number = 0;
02152     }
02153   reenable_sigpipe ();
02154   return (status);
02155 }

int TCPMEM::login const char *    name,
const char *    passwd
[virtual]
 

Reimplemented from CMS.

Definition at line 2335 of file tcpmem.cc.

02336 {
02337 #ifndef UNDER_CE
02338   if (fatal_error_occurred)
02339     {
02340       if (status >= 0)
02341         {
02342           status = CMS_MISC_ERROR;
02343         }
02344       return (status);
02345     }
02346   if (socket_fd <= 0)
02347     {
02348       rcs_print_error ("TCPMEM::write: Invalid socket descriptor. (%d)\n",
02349                        socket_fd);
02350       return (status = CMS_MISC_ERROR);
02351     }
02352   int handle_old_reply_ret = 0;
02353 
02354   while (timedout_request != NO_REMOTE_CMS_REQUEST && !handle_old_reply_ret)
02355     {
02356       handle_old_reply_ret = handle_old_replies ();
02357     }
02358   if (handle_old_reply_ret < 0)
02359     {
02360       return 0;
02361     }
02362   set_socket_fds (write_socket_fd);
02363   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
02364   *((u_long *) temp_buffer + 1) =
02365     dl_htonl ((u_long) REMOTE_CMS_GET_KEYS_REQUEST_TYPE);
02366   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
02367   if (sendn (socket_fd, temp_buffer, 20, 0, 30.0) < 0)
02368     {
02369       return 0;
02370     }
02371   memset (temp_buffer, 0, 20);
02372   strncpy (((char *) temp_buffer), name, 16);
02373   if (sendn (socket_fd, temp_buffer, 16, 0, 30.0) < 0)
02374     {
02375       return (status = CMS_MISC_ERROR);
02376     }
02377   serial_number++;
02378   if (recvn (socket_fd, temp_buffer, 20, 0, 30.0, &recvd_bytes) < 0)
02379     {
02380       return 0;
02381     }
02382   recvd_bytes = 0;
02383   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
02384   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
02385                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
02386                    socket_fd, returned_serial_number, buffer_number);
02387   if (returned_serial_number != serial_number)
02388     {
02389       rcs_print_error
02390         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
02391          returned_serial_number, serial_number);
02392       return (0);
02393     }
02394   char *crypt1_ret = rcs_crypt (passwd, ((char *) temp_buffer) + 4);
02395   if (NULL == crypt1_ret)
02396     {
02397       rcs_print_error ("TCPMEM::login() crypt function failed.\n");
02398       return 0;
02399     }
02400   char passwd_pass1[16];
02401   strncpy (passwd_pass1, crypt1_ret, 16);
02402   char *crypt2_ret = rcs_crypt (passwd_pass1, ((char *) temp_buffer) + 12);
02403   if (NULL == crypt2_ret)
02404     {
02405       rcs_print_error ("TCPMEM::login() crypt function failed.\n");
02406       return (0);
02407     }
02408   char passwd_pass2[16];
02409   strncpy (passwd_pass2, crypt2_ret, 16);
02410 
02411   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
02412   *((u_long *) temp_buffer + 1) =
02413     dl_htonl ((u_long) REMOTE_CMS_LOGIN_REQUEST_TYPE);
02414   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
02415   if (sendn (socket_fd, temp_buffer, 20, 0, 30.0) < 0)
02416     {
02417       return 0;
02418     }
02419   memset (temp_buffer, 0, 20);
02420   strncpy (((char *) temp_buffer), name, 16);
02421   if (sendn (socket_fd, temp_buffer, 16, 0, 30.0) < 0)
02422     {
02423       return (status = CMS_MISC_ERROR);
02424     }
02425   if (sendn (socket_fd, passwd_pass2, 16, 0, 30.0) < 0)
02426     {
02427       return (status = CMS_MISC_ERROR);
02428     }
02429   serial_number++;
02430   if (recvn (socket_fd, temp_buffer, 8, 0, 30.0, &recvd_bytes) < 0)
02431     {
02432       return 0;
02433     }
02434   recvd_bytes = 0;
02435   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
02436   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
02437                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
02438                    socket_fd, returned_serial_number, buffer_number);
02439   if (returned_serial_number != serial_number)
02440     {
02441       rcs_print_error
02442         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
02443          returned_serial_number, serial_number);
02444       return (status = CMS_MISC_ERROR);
02445     }
02446   int success = dl_ntohl (*((u_long *) temp_buffer + 1));
02447   return (success);
02448 #else
02449   return 0;
02450 #endif
02451 }

void TCPMEM::reconnect   [virtual]
 

Reimplemented from CMS.

Definition at line 518 of file tcpmem.cc.

Referenced by TCPMEM(), blocking_read(), check_if_read(), clear(), peek(), read(), write(), and write_if_read().

00519 {
00520   if (socket_fd > 0)
00521     {
00522       disconnect ();
00523     }
00524   subscription_count = 0;
00525   timedout_request = NO_REMOTE_CMS_REQUEST;
00526   bytes_to_throw_away = 0;
00527   recvd_bytes = 0;
00528   socket_fd = 0;
00529   waiting_for_message = 0;
00530   waiting_message_size = 0;
00531   waiting_message_id = 0;
00532   serial_number = 0;
00533 
00534   rcs_print_debug (PRINT_CMS_CONFIG_INFO, "Creating socket . . .\n");
00535 
00536   socket_fd = dl_socket (AF_INET, SOCK_STREAM, 0);
00537   if (socket_fd < 0)
00538     {
00539 #ifndef UNDER_CE
00540       rcs_print_error ("TCPMEM: Error from socket() (errno = %d:%s)\n",
00541                        errno, strerror (errno));
00542 
00543 #else
00544       rcs_print_error ("TCPMEM: Error from socket()\n");
00545 #endif
00546 
00547       status = CMS_CREATE_ERROR;
00548       return;
00549     }
00550   rcs_print_debug (PRINT_CMS_CONFIG_INFO, "Setting socket options . . . \n");
00551   if (set_tcp_socket_options (socket_fd) < 0)
00552     {
00553       return;
00554     }
00555   struct timeval tm;
00556   int socket_ret;
00557   double start_time, current_time;
00558   fd_set fds;
00559   sockaddr_in cli_addr;
00560   cli_addr.sin_family = AF_INET;
00561   cli_addr.sin_addr.s_addr = dl_htonl (INADDR_ANY);
00562   cli_addr.sin_port = dl_htons (0);
00563   rcs_print_debug (PRINT_CMS_CONFIG_INFO, "Binding . . . \n");
00564   if (dl_bind (socket_fd, (struct sockaddr *) &cli_addr, sizeof (cli_addr)) <
00565       0)
00566     {
00567 #if defined(_Windows) && !defined(USE_PCNFS) && !defined(gnuwin32)
00568       rcs_print_error ("TCPMEM: bind error %d\n", dl_WSAGetLastError ());
00569 #else
00570       rcs_print_error ("TCPMEM: bind error %d = %s\n", errno,
00571                        strerror (errno));
00572 #endif
00573       status = CMS_CREATE_ERROR;
00574     }
00575   rcs_print_debug (PRINT_CMS_CONFIG_INFO, "Connecting . . .\n");
00576   if (dl_connect (socket_fd, (struct sockaddr *) &server_socket_address,
00577                   sizeof (server_socket_address)) < 0)
00578     {
00579       if (
00580 #ifdef gnuwin32
00581            EINPROGRESS == errno
00582 #else
00583 #ifdef _Windows
00584            WSAEWOULDBLOCK == dl_WSAGetLastError ()
00585 #else
00586 #ifdef MSDOS
00587            EWOULDBLOCK == tk_geterrno (socket_fd)
00588 #else
00589            EINPROGRESS == errno
00590 #endif
00591 #endif
00592 #endif
00593         )
00594         {
00595 #ifdef _Windows
00596           tm.tv_sec = 0;
00597           tm.tv_usec = 0;
00598 #else
00599           tm.tv_sec = (long) timeout;
00600           tm.tv_sec = (long) (fmod (timeout, 1.0) * 1e6);
00601 #endif
00602           FD_ZERO (&fds);
00603           RCS_FD_SET (socket_fd, &fds);
00604           start_time = etime ();
00605           while (!(socket_ret = dl_select (socket_fd + 1,
00606                                            (fd_set *) NULL,
00607                                            &fds, (fd_set *) NULL, &tm)))
00608             {
00609               RCS_FD_SET (socket_fd, &fds);
00610               esleep (0.001);
00611               current_time = etime ();
00612               if (current_time - start_time > timeout && timeout >= 0.0)
00613                 {
00614                   if (!reconnect_needed)
00615                     {
00616                       rcs_print_error
00617                         ("TCPMEM: Timed out waiting for connection.\n");
00618                     }
00619                   status = CMS_NO_SERVER_ERROR;
00620                   return;
00621                 }
00622             }
00623 #if defined(_Windows) && !defined(gnuwin32)
00624           if (socket_ret == SOCKET_ERROR)
00625             {
00626               rcs_print_error ("select error: %d\n", dl_WSAGetLastError ());
00627               rcs_print_error ("TCPMEM: Couldn't connect.\n");
00628               status = CMS_NO_SERVER_ERROR;
00629               return;
00630             }
00631 #else
00632           if (-1 == socket_ret)
00633             {
00634 #ifndef UNDER_CE
00635               rcs_print_error ("select error: %d -- %s\n", errno,
00636                                strerror (errno));
00637 #endif
00638               rcs_print_error ("TCPMEM: Couldn't connect.\n");
00639               status = CMS_NO_SERVER_ERROR;
00640               return;
00641             }
00642 #endif
00643         }
00644       else
00645         {
00646 #if defined(_Windows) && !defined(gnuwin32)
00647           rcs_print_error ("connect error: %d\n", dl_WSAGetLastError ());
00648 #else
00649           rcs_print_error ("connect error: %d -- %s\n", errno,
00650                            strerror (errno));
00651 #endif
00652           rcs_print_error
00653             ("TCPMEM: Error trying to connect to TCP port %d of host %s(%s). sin_family=%d\n",
00654              dl_ntohs (server_socket_address.sin_port), BufferHost,
00655              dl_inet_ntoa (server_socket_address.sin_addr),
00656              server_socket_address.sin_family);
00657           status = CMS_NO_SERVER_ERROR;
00658           return;
00659         }
00660     }
00661   read_socket_fd = socket_fd;
00662 
00663   memset (temp_buffer, 0, 32);
00664   if (total_subdivisions > 1)
00665     {
00666       subscription_type = CMS_NO_SUBSCRIPTION;
00667     }
00668 
00669   if (subscription_type != CMS_NO_SUBSCRIPTION)
00670     {
00671       verify_bufname ();
00672       if (status < 0)
00673         {
00674           rcs_print_error ("TCPMEM: verify_bufname() failed\n");
00675           return;
00676         }
00677       *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00678       *((u_long *) temp_buffer + 1) =
00679         dl_htonl ((u_long) REMOTE_CMS_SET_SUBSCRIPTION_REQUEST_TYPE);
00680       *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00681       *((u_long *) temp_buffer + 3) = dl_htonl ((u_long) subscription_type);
00682       *((u_long *) temp_buffer + 4) =
00683         dl_htonl ((u_long) poll_interval_millis);
00684       if (sendn (socket_fd, temp_buffer, 20, 0, 30) < 0)
00685         {
00686           rcs_print_error ("Can`t setup subscription.\n");
00687           subscription_type = CMS_NO_SUBSCRIPTION;
00688         }
00689       else
00690         {
00691           serial_number++;
00692           rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
00693                            "TCPMEM sending request: fd = %d, serial_number=%d, request_type=%d, buffer_number=%d\n",
00694                            socket_fd, serial_number,
00695                            dl_ntohl (*((u_long *) temp_buffer + 1)),
00696                            buffer_number);
00697           memset (temp_buffer, 0, 20);
00698           recvd_bytes = 0;
00699           if (recvn (socket_fd, temp_buffer, 8, 0, 30, &recvd_bytes) < 0)
00700             {
00701               rcs_print_error ("Can`t setup subscription.\n");
00702               subscription_type = CMS_NO_SUBSCRIPTION;
00703             }
00704           if (!dl_ntohl (*((u_long *) temp_buffer) + 1))
00705             {
00706               rcs_print_error ("Can`t setup subscription.\n");
00707               subscription_type = CMS_NO_SUBSCRIPTION;
00708             }
00709 
00710           bytes_to_throw_away = 8 - recvd_bytes;
00711           if (bytes_to_throw_away < 0 || bytes_to_throw_away > 8)
00712             {
00713               bytes_to_throw_away = 0;
00714             }
00715           recvd_bytes = 0;
00716         }
00717       memset (temp_buffer, 0, 20);
00718     }
00719   if (subscription_type != CMS_NO_SUBSCRIPTION)
00720     {
00721       polling = 1;
00722     }
00723 
00724 
00725   if (polling)
00726     {
00727       make_tcp_socket_nonblocking (socket_fd);
00728       write_socket_fd = dl_socket (AF_INET, SOCK_STREAM, 0);
00729       if (write_socket_fd < 0)
00730         {
00731 #ifndef UNDER_CE
00732           rcs_print_error ("TCPMEM: Error from socket() (errno = %d:%s)\n",
00733                            errno, strerror (errno));
00734 #else
00735           rcs_print_error ("TCPMEM: Error from socket()\n");
00736 #endif
00737           status = CMS_CREATE_ERROR;
00738           return;
00739         }
00740       rcs_print_debug (PRINT_CMS_CONFIG_INFO,
00741                        "Setting socket options . . . \n");
00742       if (set_tcp_socket_options (write_socket_fd) < 0)
00743         {
00744           return;
00745         }
00746       rcs_print_debug (PRINT_CMS_CONFIG_INFO, "Binding . . . \n");
00747       if (dl_bind
00748           (write_socket_fd, (struct sockaddr *) &cli_addr,
00749            sizeof (cli_addr)) < 0)
00750         {
00751 #if defined(_Windows) && !defined(USE_PCNFS) && !defined(gnuwin32)
00752           rcs_print_error ("TCPMEM: bind error %d\n", dl_WSAGetLastError ());
00753 #else
00754           rcs_print_error ("TCPMEM: bind error %d = %s\n", errno,
00755                            strerror (errno));
00756 #endif
00757           status = CMS_CREATE_ERROR;
00758         }
00759       rcs_print_debug (PRINT_CMS_CONFIG_INFO, "Connecting . . .\n");
00760       if (dl_connect
00761           (write_socket_fd, (struct sockaddr *) &server_socket_address,
00762            sizeof (server_socket_address)) < 0)
00763         {
00764           if (
00765 #ifdef gnuwin32
00766                EINPROGRESS == errno
00767 #else
00768 #ifdef _Windows
00769                WSAEWOULDBLOCK == dl_WSAGetLastError ()
00770 #else
00771 #ifdef MSDOS
00772                EWOULDBLOCK == tk_geterrno (write_socket_fd)
00773 #else
00774                EINPROGRESS == errno
00775 #endif
00776 #endif
00777 #endif
00778             )
00779             {
00780               FD_ZERO (&fds);
00781               RCS_FD_SET (write_socket_fd, &fds);
00782               start_time = etime ();
00783               while (!(socket_ret = dl_select (write_socket_fd + 1,
00784                                                (fd_set *) NULL,
00785                                                &fds, (fd_set *) NULL, &tm)))
00786                 {
00787                   RCS_FD_SET (write_socket_fd, &fds);
00788                   esleep (0.001);
00789                   current_time = etime ();
00790                   if (current_time - start_time > timeout && timeout >= 0.0)
00791                     {
00792                       rcs_print_error
00793                         ("TCPMEM: Timed out waiting for connection.\n");
00794                       status = CMS_NO_SERVER_ERROR;
00795                       return;
00796                     }
00797                 }
00798 #if defined(_Windows) && !defined(gnuwin32)
00799               if (socket_ret == SOCKET_ERROR)
00800                 {
00801                   rcs_print_error ("select error: %d\n",
00802                                    dl_WSAGetLastError ());
00803                   rcs_print_error ("TCPMEM: Couldn't connect.\n");
00804                   status = CMS_NO_SERVER_ERROR;
00805                   return;
00806                 }
00807 #else
00808               if (-1 == socket_ret)
00809                 {
00810 #ifndef UNDER_CE
00811                   rcs_print_error ("select error: %d -- %s\n", errno,
00812                                    strerror (errno));
00813 #endif
00814                   rcs_print_error ("TCPMEM: Couldn't connect.\n");
00815                   status = CMS_NO_SERVER_ERROR;
00816                   return;
00817                 }
00818 #endif
00819             }
00820           else
00821             {
00822 #if defined(_Windows) && !defined(gnuwin32)
00823               rcs_print_error ("connect error: %d\n", dl_WSAGetLastError ());
00824 #else
00825               rcs_print_error ("connect error: %d -- %s\n", errno,
00826                                strerror (errno));
00827 #endif
00828               rcs_print_error
00829                 ("TCPMEM: Error trying to connect to TCP port %d of host %s.\n",
00830                  dl_ntohs (server_socket_address.sin_port), BufferHost);
00831             }
00832         }
00833       timeout = 0;
00834     }
00835   else
00836     {
00837       write_socket_fd = read_socket_fd;
00838     }
00839   reconnect_needed = 0;
00840   fatal_error_occurred = 0;
00841 
00842 }

void TCPMEM::disconnect   [virtual]
 

Reimplemented from CMS.

Definition at line 859 of file tcpmem.cc.

Referenced by reconnect(), and ~TCPMEM().

00860 {
00861   if (write_socket_fd > 0 && write_socket_fd != socket_fd)
00862     {
00863       if (status != CMS_CONFIG_ERROR && status != CMS_CREATE_ERROR)
00864         {
00865           if (delete_totally)
00866             {
00867               *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00868               *((u_long *) temp_buffer + 1) =
00869                 dl_htonl ((u_long) REMOTE_CMS_CLEAN_REQUEST_TYPE);
00870               *((u_long *) temp_buffer + 2) =
00871                 dl_htonl ((u_long) buffer_number);
00872               sendn (write_socket_fd, temp_buffer, 20, 0, -1);
00873             }
00874         }
00875       dl_closesocket (write_socket_fd);
00876       write_socket_fd = 0;
00877     }
00878 
00879   if (socket_fd > 0)
00880     {
00881       if (status != CMS_CONFIG_ERROR && status != CMS_CREATE_ERROR)
00882         {
00883           if (delete_totally)
00884             {
00885               *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00886               *((u_long *) temp_buffer + 1) =
00887                 dl_htonl ((u_long) REMOTE_CMS_CLEAN_REQUEST_TYPE);
00888               *((u_long *) temp_buffer + 2) =
00889                 dl_htonl ((u_long) buffer_number);
00890               sendn (socket_fd, temp_buffer, 20, 0, -1);
00891             }
00892         }
00893       dl_closesocket (socket_fd);
00894       socket_fd = 0;
00895     }
00896 }

CMS_DIAGNOSTICS_INFO * TCPMEM::get_diagnostics_info   [virtual]
 

Reimplemented from CMS.

Definition at line 344 of file tcpmem.cc.

00345 {
00346   if (polling)
00347     {
00348       return (NULL);
00349     }
00350   disable_sigpipe ();
00351 
00352   if (((int) handle_old_replies ()) < 0)
00353     {
00354       reenable_sigpipe ();
00355       return (NULL);
00356     }
00357 
00358   set_socket_fds (read_socket_fd);
00359 
00360   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00361   *((u_long *) temp_buffer + 1) =
00362     dl_htonl ((u_long) REMOTE_CMS_GET_DIAG_INFO_REQUEST_TYPE);
00363   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00364   if (sendn (socket_fd, temp_buffer, 20, 0, timeout) < 0)
00365     {
00366       reconnect_needed = 1;
00367       fatal_error_occurred = 1;
00368       reenable_sigpipe ();
00369       status = CMS_MISC_ERROR;
00370       return (NULL);
00371     }
00372   memset (temp_buffer, 0, 0x2000);
00373   serial_number++;
00374   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
00375                    "TCPMEM sending request: fd = %d, serial_number=%d, request_type=%d, buffer_number=%d\n",
00376                    socket_fd, serial_number,
00377                    dl_ntohl (*((u_long *) temp_buffer + 1)), buffer_number);
00378   if (recvn (socket_fd, temp_buffer, 32, 0, -1.0, &recvd_bytes) < 0)
00379     {
00380       if (recvn_timedout)
00381         {
00382           bytes_to_throw_away = 32;
00383         }
00384       return (NULL);
00385     }
00386   recvd_bytes = 0;
00387   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00388   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
00389                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
00390                    socket_fd, returned_serial_number, buffer_number);
00391   if (returned_serial_number != serial_number)
00392     {
00393       rcs_print_error
00394         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00395          returned_serial_number, serial_number);
00396       reconnect_needed = 1;
00397       fatal_error_occurred = 1;
00398       reenable_sigpipe ();
00399       status = CMS_MISC_ERROR;
00400       return (NULL);
00401     }
00402   status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00403   if (status < 0)
00404     {
00405       return (NULL);
00406     }
00407   if (NULL == di)
00408     {
00409       di = new CMS_DIAGNOSTICS_INFO ();
00410       di->dpis = new RCS_LINKED_LIST ();
00411     }
00412   else
00413     {
00414       di->dpis->delete_members ();
00415     }
00416   di->last_writer_dpi = NULL;
00417   di->last_reader_dpi = NULL;
00418   di->last_writer = dl_ntohl (*((u_long *) temp_buffer + 2));
00419   di->last_reader = dl_ntohl (*((u_long *) temp_buffer + 3));
00420   double server_time;
00421   memcpy (&server_time, temp_buffer + 16, 8);
00422   double local_time = etime ();
00423   double diff_time = local_time - server_time;
00424   int dpi_count = dl_ntohl (*((u_long *) temp_buffer + 6));
00425   int dpi_max_size = dl_ntohl (*((u_long *) temp_buffer + 7));
00426   if (dpi_max_size > 32 && dpi_max_size < 0x2000)
00427     {
00428       if (recvn
00429           (socket_fd, temp_buffer + 32, dpi_max_size - 32, 0, -1.0,
00430            &recvd_bytes) < 0)
00431         {
00432           if (recvn_timedout)
00433             {
00434               bytes_to_throw_away = dpi_max_size - 32;
00435               return (NULL);
00436             }
00437         }
00438       recvd_bytes = 0;
00439       int dpi_offset = 32;
00440       CMS_DIAG_PROC_INFO cms_dpi;
00441       for (int i = 0; i < dpi_count && dpi_offset < dpi_max_size; i++)
00442         {
00443           memset (&cms_dpi, 0, sizeof (CMS_DIAG_PROC_INFO));
00444           memcpy (cms_dpi.name, temp_buffer + dpi_offset, 16);
00445           dpi_offset += 16;
00446           memcpy (cms_dpi.host_sysinfo, temp_buffer + dpi_offset, 32);
00447           dpi_offset += 32;
00448           cms_dpi.pid =
00449             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00450           dpi_offset += 4;
00451           memcpy (&(cms_dpi.rcslib_ver), temp_buffer + dpi_offset, 8);
00452           dpi_offset += 8;
00453           cms_dpi.access_type =
00454             (CMS_INTERNAL_ACCESS_TYPE)
00455             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00456           dpi_offset += 4;
00457           cms_dpi.msg_id =
00458             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00459           dpi_offset += 4;
00460           cms_dpi.msg_size =
00461             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00462           dpi_offset += 4;
00463           cms_dpi.msg_type =
00464             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00465           dpi_offset += 4;
00466           cms_dpi.number_of_accesses =
00467             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00468           dpi_offset += 4;
00469           cms_dpi.number_of_new_messages =
00470             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00471           dpi_offset += 4;
00472           memcpy (&(cms_dpi.bytes_moved), temp_buffer + dpi_offset, 8);
00473           dpi_offset += 8;
00474           memcpy (&(cms_dpi.bytes_moved_across_socket),
00475                   temp_buffer + dpi_offset, 8);
00476           dpi_offset += 8;
00477           memcpy (&(cms_dpi.last_access_time), temp_buffer + dpi_offset, 8);
00478           if (cmsdiag_timebias_set)
00479             {
00480               cms_dpi.last_access_time += diff_time - cmsdiag_timebias;
00481             }
00482           dpi_offset += 8;
00483           memcpy (&(cms_dpi.first_access_time), temp_buffer + dpi_offset, 8);
00484           if (cmsdiag_timebias_set)
00485             {
00486               cms_dpi.first_access_time += diff_time - cmsdiag_timebias;
00487             }
00488           dpi_offset += 8;
00489           memcpy (&(cms_dpi.min_difference), temp_buffer + dpi_offset, 8);
00490           dpi_offset += 8;
00491           memcpy (&(cms_dpi.max_difference), temp_buffer + dpi_offset, 8);
00492           dpi_offset += 8;
00493           di->dpis->store_at_tail (&cms_dpi, sizeof (CMS_DIAG_PROC_INFO), 1);
00494           int is_last_writer =
00495             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00496           dpi_offset += 4;
00497           if (is_last_writer)
00498             {
00499               di->last_writer_dpi =
00500                 (CMS_DIAG_PROC_INFO *) di->dpis->get_tail ();
00501             }
00502           int is_last_reader =
00503             dl_ntohl (*((u_long *) ((char *) temp_buffer + dpi_offset)));
00504           dpi_offset += 4;
00505           if (is_last_reader)
00506             {
00507               di->last_reader_dpi =
00508                 (CMS_DIAG_PROC_INFO *) di->dpis->get_tail ();
00509             }
00510         }
00511     }
00512   reenable_sigpipe ();
00513   return di;
00514 }

CMS_STATUS TCPMEM::handle_old_replies   [protected]
 

Definition at line 900 of file tcpmem.cc.

Referenced by blocking_read(), check_if_read(), clear(), get_diagnostics_info(), login(), peek(), read(), write(), and write_if_read().

00901 {
00902   long message_size;
00903 
00904   timedout_request_writeid = 0;
00905   switch (timedout_request)
00906     {
00907     case REMOTE_CMS_READ_REQUEST_TYPE:
00908       if (!waiting_for_message)
00909         {
00910           if (recvn (socket_fd, temp_buffer, 20, 0, timeout, &recvd_bytes) <
00911               0)
00912             {
00913               if (recvn_timedout)
00914                 {
00915                   if (polling)
00916                     {
00917                       return status;
00918                     }
00919                   else
00920                     {
00921                       consecutive_timeouts++;
00922                       if (consecutive_timeouts > max_consecutive_timeouts &&
00923                           max_consecutive_timeouts > 0)
00924                         {
00925                           rcs_print_error
00926                             ("CMS: %d consecutive timeouts have occurred. -- Stop trying.\n",
00927                              consecutive_timeouts);
00928                           fatal_error_occurred = 1;
00929                           reconnect_needed = 1;
00930                         }
00931                       return (status = CMS_TIMED_OUT);
00932                     }
00933                 }
00934               else
00935                 {
00936                   recvd_bytes = 0;
00937                   fatal_error_occurred = 1;
00938                   return (status = CMS_MISC_ERROR);
00939                 }
00940             }
00941           recvd_bytes = 0;
00942           returned_serial_number =
00943             (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00944           rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
00945                            "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
00946                            socket_fd, returned_serial_number, buffer_number);
00947           if (returned_serial_number != serial_number)
00948             {
00949               rcs_print_error
00950                 ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00951                  returned_serial_number, serial_number);
00952               if (subscription_type == CMS_NO_SUBSCRIPTION)
00953                 {
00954                   fatal_error_occurred = 1;
00955                   reconnect_needed = 1;
00956                   return (status = CMS_MISC_ERROR);
00957                 }
00958               else
00959                 {
00960                   serial_number = returned_serial_number;
00961                 }
00962             }
00963           message_size = dl_ntohl (*((u_long *) temp_buffer + 2));
00964           timedout_request_status =
00965             (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00966           timedout_request_writeid = dl_ntohl (*((u_long *) temp_buffer + 3));
00967           header.was_read = dl_ntohl (*((u_long *) temp_buffer + 4));
00968           if (message_size > max_encoded_message_size)
00969             {
00970               rcs_print_error ("Recieved message is too big. (%ld > %ld)\n",
00971                                message_size, max_encoded_message_size);
00972               fatal_error_occurred = 1;
00973               reconnect_needed = 1;
00974               return (status = CMS_INSUFFICIENT_SPACE_ERROR);
00975             }
00976         }
00977       else
00978         {
00979           message_size = waiting_message_size;
00980         }
00981       if (message_size > 0)
00982         {
00983           if (recvn
00984               (socket_fd, encoded_data, message_size, 0, timeout,
00985                &recvd_bytes) < 0)
00986             {
00987               if (recvn_timedout)
00988                 {
00989                   if (!waiting_for_message)
00990                     {
00991                       waiting_message_id = timedout_request_writeid;
00992                       waiting_message_size = message_size;
00993                     }
00994                   waiting_for_message = 1;
00995                   timedout_request_writeid = 0;
00996                   if (polling)
00997                     {
00998                       return status;
00999                     }
01000                   else
01001                     {
01002                       consecutive_timeouts++;
01003                       if (consecutive_timeouts > max_consecutive_timeouts &&
01004                           max_consecutive_timeouts > 0)
01005                         {
01006                           rcs_print_error
01007                             ("CMS: %d consecutive timeouts have occurred. -- Stop trying.\n",
01008                              consecutive_timeouts);
01009                           fatal_error_occurred = 1;
01010                           reconnect_needed = 1;
01011                         }
01012                       return (status = CMS_TIMED_OUT);
01013                     }
01014                 }
01015               else
01016                 {
01017                   recvd_bytes = 0;
01018                   fatal_error_occurred = 1;
01019                   reconnect_needed = 1;
01020                   return (status = CMS_MISC_ERROR);
01021                 }
01022             }
01023           recvd_bytes = 0;
01024           if (waiting_for_message)
01025             {
01026               timedout_request_writeid = waiting_message_id;
01027             }
01028         }
01029       break;
01030 
01031     case REMOTE_CMS_WRITE_REQUEST_TYPE:
01032     case REMOTE_CMS_CHECK_IF_READ_REQUEST_TYPE:
01033       if (timedout_request == REMOTE_CMS_WRITE_REQUEST_TYPE &&
01034           (min_compatible_version > 2.58 || min_compatible_version < 1e-6 ||
01035            confirm_write))
01036         {
01037           break;
01038         }
01039       if (recvn (socket_fd, temp_buffer, 12, 0, timeout, &recvd_bytes) < 0)
01040         {
01041           if (recvn_timedout)
01042             {
01043               consecutive_timeouts++;
01044               if (consecutive_timeouts > max_consecutive_timeouts &&
01045                   max_consecutive_timeouts > 0)
01046                 {
01047                   rcs_print_error
01048                     ("CMS: %d consecutive timeouts have occurred. -- Stop trying.\n",
01049                      consecutive_timeouts);
01050                   reconnect_needed = 1;
01051                   fatal_error_occurred = 1;
01052                 }
01053               reconnect_needed = 1;
01054               return (status = CMS_TIMED_OUT);
01055             }
01056           else
01057             {
01058               fatal_error_occurred = 1;
01059               reconnect_needed = 1;
01060               return (status = CMS_MISC_ERROR);
01061             }
01062         }
01063       recvd_bytes = 0;
01064       returned_serial_number =
01065         (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
01066       rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
01067                        "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
01068                        socket_fd, returned_serial_number, buffer_number);
01069       if (returned_serial_number != serial_number)
01070         {
01071           rcs_print_error
01072             ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
01073              returned_serial_number, serial_number);
01074           reconnect_needed = 1;
01075           if (subscription_type == CMS_NO_SUBSCRIPTION)
01076             {
01077               return (status = CMS_MISC_ERROR);
01078             }
01079         }
01080       break;
01081 
01082     case REMOTE_CMS_CLEAR_REQUEST_TYPE:
01083       if (recvn (socket_fd, temp_buffer, 4, 0, timeout, &recvd_bytes) < 0)
01084         {
01085           if (recvn_timedout)
01086             {
01087               consecutive_timeouts++;
01088               reconnect_needed = 1;
01089               if (consecutive_timeouts > max_consecutive_timeouts &&
01090                   max_consecutive_timeouts > 0)
01091                 {
01092                   rcs_print_error
01093                     ("CMS: %d consecutive timeouts have occurred. -- Stop trying.\n",
01094                      consecutive_timeouts);
01095                   fatal_error_occurred = 1;
01096                 }
01097               return (status = CMS_TIMED_OUT);
01098             }
01099           else
01100             {
01101               reconnect_needed = 1;
01102               fatal_error_occurred = 1;
01103               return (status = CMS_MISC_ERROR);
01104             }
01105         }
01106       recvd_bytes = 0;
01107       returned_serial_number =
01108         (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
01109       rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
01110                        "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
01111                        socket_fd, returned_serial_number, buffer_number);
01112       if (returned_serial_number != serial_number)
01113         {
01114           rcs_print_error
01115             ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
01116              returned_serial_number, serial_number);
01117           reconnect_needed = 1;
01118           if (subscription_type == CMS_NO_SUBSCRIPTION)
01119             {
01120               return (status = CMS_MISC_ERROR);
01121             }
01122         }
01123       break;
01124 
01125 
01126 
01127     case NO_REMOTE_CMS_REQUEST:
01128     default:
01129       break;
01130     }
01131   if (bytes_to_throw_away > 0)
01132     {
01133       if (recvn
01134           (socket_fd, encoded_data, bytes_to_throw_away, 0, timeout,
01135            &recvd_bytes) < 0)
01136         {
01137           if (recvn_timedout)
01138             {
01139               consecutive_timeouts++;
01140               if (consecutive_timeouts > max_consecutive_timeouts &&
01141                   max_consecutive_timeouts > 0)
01142                 {
01143                   rcs_print_error
01144                     ("CMS: %d consecutive timeouts have occurred. -- Stop trying.\n",
01145                      consecutive_timeouts);
01146                   fatal_error_occurred = 1;
01147                   reconnect_needed = 1;
01148                 }
01149               return (status = CMS_TIMED_OUT);
01150             }
01151           else
01152             {
01153               recvd_bytes = 0;
01154               fatal_error_occurred = 1;
01155               reconnect_needed = 1;
01156               return (status = CMS_MISC_ERROR);
01157             }
01158         }
01159       recvd_bytes = 0;
01160     }
01161   bytes_to_throw_away = 0;
01162   timedout_request = NO_REMOTE_CMS_REQUEST;
01163   consecutive_timeouts = 0;
01164   waiting_for_message = 0;
01165   waiting_message_size = 0;
01166   waiting_message_id = 0;
01167   recvd_bytes = 0;
01168   return status;
01169 }

void TCPMEM::send_diag_info   [protected]
 

Definition at line 230 of file tcpmem.cc.

Referenced by TCPMEM().

00231 {
00232   if (polling)
00233     {
00234       return;
00235     }
00236   if (NULL == dpi)
00237     {
00238       return;
00239     }
00240   disable_sigpipe ();
00241 
00242   set_socket_fds (read_socket_fd);
00243   memset (diag_info_buf, 0, 88);
00244   *((u_long *) diag_info_buf) = dl_htonl ((u_long) serial_number);
00245   *((u_long *) diag_info_buf + 1) =
00246     dl_htonl ((u_long) REMOTE_CMS_SET_DIAG_INFO_REQUEST_TYPE);
00247   *((u_long *) diag_info_buf + 2) = dl_htonl ((u_long) buffer_number);
00248   strncpy (diag_info_buf + 20, dpi->name, 16);
00249   strncpy (diag_info_buf + 36, dpi->host_sysinfo, 32);
00250   *((u_long *) (diag_info_buf + 68)) = dl_htonl ((u_long) dpi->pid);
00251   *((u_long *) (diag_info_buf + 72)) = dl_htonl ((u_long) connection_number);
00252   memcpy (diag_info_buf + 76, &(dpi->rcslib_ver), 8);
00253   *((u_long *) (diag_info_buf + 84)) = 0x11223344;
00254   if (sendn (socket_fd, diag_info_buf, 88, 0, timeout) < 0)
00255     {
00256       reconnect_needed = 1;
00257       fatal_error_occurred = 1;
00258       reenable_sigpipe ();
00259       status = CMS_MISC_ERROR;
00260       return;
00261     }
00262   serial_number++;
00263   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
00264                    "TCPMEM sending request: fd = %d, serial_number=%d, request_type=%d, buffer_number=%d\n",
00265                    socket_fd, serial_number,
00266                    dl_ntohl (*((u_long *) diag_info_buf + 1)), buffer_number);
00267   reenable_sigpipe ();
00268 
00269 }

void TCPMEM::set_socket_fds int    new_fd [protected]
 

Definition at line 2455 of file tcpmem.cc.

Referenced by blocking_read(), check_if_read(), clear(), get_diagnostics_info(), login(), peek(), read(), send_diag_info(), verify_bufname(), write(), and write_if_read().

02456 {
02457   if (socket_fd == read_socket_fd)
02458     {
02459       read_serial_number = serial_number;
02460     }
02461   if (socket_fd == write_socket_fd)
02462     {
02463       write_serial_number = serial_number;
02464     }
02465   socket_fd = new_fd;
02466   if (socket_fd == read_socket_fd)
02467     {
02468       serial_number = read_serial_number;
02469     }
02470   if (socket_fd == write_socket_fd)
02471     {
02472       serial_number = write_serial_number;
02473     }
02474 }

void TCPMEM::disable_sigpipe   [protected]
 

Definition at line 1639 of file tcpmem.cc.

Referenced by blocking_read(), check_if_read(), get_diagnostics_info(), peek(), read(), send_diag_info(), verify_bufname(), write(), and write_if_read().

01640 {
01641 #ifndef MSDOS
01642   if (!autoreconnect)
01643     {
01644       return;
01645     }
01646   old_handler = signal (SIGPIPE, tcpmem_sigpipe_handler);
01647   if (tcpmem_sigpipe_count > sigpipe_count)
01648     {
01649       sigpipe_count = tcpmem_sigpipe_count;
01650     }
01651 #endif
01652 }

void TCPMEM::reenable_sigpipe   [protected]
 

Definition at line 1622 of file tcpmem.cc.

Referenced by blocking_read(), check_if_read(), get_diagnostics_info(), peek(), read(), send_diag_info(), verify_bufname(), write(), and write_if_read().

01623 {
01624 #ifndef MSDOS
01625   if (old_handler != ((void (*)(int)) SIG_ERR))
01626     {
01627       signal (SIGPIPE, old_handler);
01628     }
01629   old_handler = (void (*)(int)) SIG_ERR;
01630   if (tcpmem_sigpipe_count > sigpipe_count)
01631     {
01632       sigpipe_count = tcpmem_sigpipe_count;
01633       reconnect_needed = 1;
01634     }
01635 #endif
01636 }

void TCPMEM::verify_bufname   [protected]
 

Definition at line 272 of file tcpmem.cc.

Referenced by TCPMEM(), and reconnect().

00273 {
00274   if (polling)
00275     {
00276       return;
00277     }
00278   disable_sigpipe ();
00279 
00280   set_socket_fds (read_socket_fd);
00281 
00282   *((u_long *) temp_buffer) = dl_htonl ((u_long) serial_number);
00283   *((u_long *) temp_buffer + 1) =
00284     dl_htonl ((u_long) REMOTE_CMS_GET_BUF_NAME_REQUEST_TYPE);
00285   *((u_long *) temp_buffer + 2) = dl_htonl ((u_long) buffer_number);
00286   if (sendn (socket_fd, temp_buffer, 20, 0, timeout) < 0)
00287     {
00288       reconnect_needed = 1;
00289       fatal_error_occurred = 1;
00290       reenable_sigpipe ();
00291       status = CMS_MISC_ERROR;
00292       return;
00293     }
00294   serial_number++;
00295   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
00296                    "TCPMEM sending request: fd = %d, serial_number=%d, request_type=%d, buffer_number=%d\n",
00297                    socket_fd, serial_number,
00298                    dl_ntohl (*((u_long *) temp_buffer + 1)), buffer_number);
00299   if (recvn (socket_fd, temp_buffer, 40, 0, timeout, &recvd_bytes) < 0)
00300     {
00301       if (recvn_timedout)
00302         {
00303           bytes_to_throw_away = 40;
00304           return;
00305         }
00306     }
00307   returned_serial_number = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer));
00308   rcs_print_debug (PRINT_ALL_SOCKET_REQUESTS,
00309                    "TCPMEM recieved_reply: fd = %d, serial_number=%d, buffer_number=%d\n",
00310                    socket_fd, returned_serial_number, buffer_number);
00311   if (returned_serial_number != serial_number)
00312     {
00313       rcs_print_error
00314         ("TCPMEM: Returned serial number(%d) does not match expected serial number(%d).\n",
00315          returned_serial_number, serial_number);
00316       reconnect_needed = 1;
00317       fatal_error_occurred = 1;
00318       reenable_sigpipe ();
00319       status = CMS_MISC_ERROR;
00320       return;
00321     }
00322   status = (CMS_STATUS) dl_ntohl (*((u_long *) temp_buffer + 1));
00323   if (status < 0)
00324     {
00325       return;
00326     }
00327   if (strncmp (temp_buffer + 8, BufferName, 31))
00328     {
00329       rcs_print_error
00330         ("TCPMEM: The buffer (%s) is registered on TCP port %d of host %s with buffer number %d.\n",
00331          ((char *) temp_buffer + 8), tcp_port_number, BufferHost,
00332          buffer_number);
00333       rcs_print_error
00334         ("TCPMEM: However, this process (%s) is attempting to connect to the buffer %s at the same location.\n",
00335          ProcessName, BufferName);
00336       status = CMS_RESOURCE_CONFLICT_ERROR;
00337       return;
00338     }
00339   reenable_sigpipe ();
00340 }


Field Documentation

char TCPMEM::diag_info_buf[0x400] [protected]
 

Definition at line 43 of file tcpmem.hh.

int TCPMEM::recvd_bytes [protected]
 

Definition at line 44 of file tcpmem.hh.

long TCPMEM::serial_number [protected]
 

Definition at line 45 of file tcpmem.hh.

long TCPMEM::returned_serial_number [protected]
 

Definition at line 46 of file tcpmem.hh.

int TCPMEM::subscription_type [protected]
 

Definition at line 47 of file tcpmem.hh.

int TCPMEM::poll_interval_millis [protected]
 

Definition at line 48 of file tcpmem.hh.

struct hostent* TCPMEM::server_host_entry [protected]
 

Definition at line 50 of file tcpmem.hh.

struct sockaddr_in TCPMEM::server_socket_address [protected]
 

Definition at line 52 of file tcpmem.hh.

int TCPMEM::socket_fd [protected]
 

Definition at line 53 of file tcpmem.hh.

char TCPMEM::temp_buffer[0x2000] [protected]
 

Definition at line 54 of file tcpmem.hh.

REMOTE_CMS_REQUEST_TYPE TCPMEM::timedout_request [protected]
 

Definition at line 55 of file tcpmem.hh.

long TCPMEM::bytes_to_throw_away [protected]
 

Definition at line 56 of file tcpmem.hh.

int TCPMEM::polling [protected]
 

Definition at line 57 of file tcpmem.hh.

int TCPMEM::write_socket_fd [protected]
 

Definition at line 58 of file tcpmem.hh.

int TCPMEM::read_socket_fd [protected]
 

Definition at line 59 of file tcpmem.hh.

long TCPMEM::write_serial_number [protected]
 

Definition at line 60 of file tcpmem.hh.

long TCPMEM::read_serial_number [protected]
 

Definition at line 61 of file tcpmem.hh.

CMS_STATUS TCPMEM::timedout_request_status [protected]
 

Definition at line 63 of file tcpmem.hh.

unsigned long TCPMEM::timedout_request_writeid [protected]
 

Definition at line 64 of file tcpmem.hh.

int TCPMEM::max_consecutive_timeouts [protected]
 

Definition at line 65 of file tcpmem.hh.

int TCPMEM::waiting_for_message [protected]
 

Definition at line 66 of file tcpmem.hh.

unsigned long TCPMEM::waiting_message_size [protected]
 

Definition at line 67 of file tcpmem.hh.

unsigned long TCPMEM::waiting_message_id [protected]
 

Definition at line 68 of file tcpmem.hh.

int TCPMEM::autoreconnect [protected]
 

Definition at line 69 of file tcpmem.hh.

int TCPMEM::reconnect_needed [protected]
 

Definition at line 70 of file tcpmem.hh.

int TCPMEM::sigpipe_count [protected]
 

Definition at line 71 of file tcpmem.hh.

void(* TCPMEM::old_handler)(int) [protected]
 

int TCPMEM::subscription_count [protected]
 

Definition at line 76 of file tcpmem.hh.


The documentation for this class was generated from the following files:
Generated on Sun Dec 2 15:59:24 2001 for rcslib by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001