Bdb packages | Design docs | Source docs | Guidelines | Recent releases

Search | Site Map .

Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

/BdbTransfer/BdbPTRemoteCopyRecv.cc

Go to the documentation of this file.
00001 //------------------------------------------------------------------------------
00002 // File and Version Information:
00003 //      $Id: BdbPTRemoteCopyRecv.cc,v 1.10 1999/07/27 00:03:55 svarovsk Exp $
00004 //
00005 // Description:
00006 //      'sender' class derived from 'transfer' class
00007 //      gets data from socket, calculate checksum and writes to file
00008 //      file and socket must be opened and connected by caller
00009 //
00010 // Environment:
00011 //      Software developed for the BaBar Detector at the SLAC B-Factory
00012 //
00013 // Author:
00014 //      Gennadi S. Svarovski (svarovsk@slac.stanford.edu)
00015 //          original author
00016 //
00017 // Copyright Information:
00018 //      Copyright (C) 1999      Stanford Linear Accelerator Center
00019 //
00020 //------------------------------------------------------------------------------
00021 #include "BaBar/BaBar.hh"
00022 
00023 
00024 #include <sys/types.h>
00025 #include <unistd.h>
00026 #include <stdio.h>
00027 #include <stdlib.h>
00028 #include <assert.h>
00029 
00030 #include "BdbTransfer/BdbPTosSpecific.h"
00031 #include "BdbTransfer/BdbPTChecksumSum.h"
00032 #include "BdbTransfer/BdbPTRemoteCopyError.h"
00033 #include "BdbTransfer/BdbPTVerbose.h"
00034 #include "BdbTransfer/BdbPTRemoteCopyRecv.h"
00035 
00036 static char cvsid[]="$Id: BdbPTRemoteCopyRecv.cc,v 1.10 1999/07/27 00:03:55 svarovsk Exp $";
00037 
00038 void* BdbPTRemoteCopyRecv::run( void ) {
00039     int i, returnstatus = 0;
00040     char *buffer;
00041     
00042     VERBOSEMSG( 3, ( "receiver started ( number=%2d, total=%2d, started=%2d, bufsize=%d )\n",
00043                      num, total, started, bufsize ) );
00044 
00045     buffer = new char [bufsize];
00046     assert( buffer != NULL );
00047 
00048     // main loop across all blocks for this thread
00049     for( i = num; i < total; i += started ) {
00050         BdbPTChecksumSum sum;
00051         off_t offset;
00052         ssize_t len;
00053         size_t blocklen = 0, blockoff;
00054         unsigned blocknum;
00055         unsigned intSum;
00056         BdbPTRemoteCopyResult result = GOOD;
00057         
00058         // reading block number, size and checksum from sender
00059         if( socket.readInt( (int*)&blocknum ) <= 0 ||
00060             socket.readInt( (int*)&blocklen ) <= 0 ||
00061             socket.readInt( (int*)&intSum   ) <= 0 ) {
00062                 returnstatus = 2;
00063                 break;
00064         }
00065 
00066         // need to make loop here to read all sender wants to tell us
00067         // packets got fragmented since it is very unlikely we use
00068         // network with MTU ~1M (reasonable size of buffer)
00069         for( blockoff = 0; blockoff < blocklen; blockoff += len )
00070             len = socket.read( buffer + blockoff, blocklen - blockoff );
00071 
00072         VERBOSEMSG( 2, ( "received ( thread=%2d, block=%d, size=%d, checksum=%08X )\n",
00073                          num, blocknum, blocklen, intSum ) );
00074 
00075         if( !(transferOptions & BDBTRANSFER_NOCHECKSUM ) ) {
00076             sum = BdbPTChecksumSum::calculate( buffer, blocklen, NULL );
00077 
00078             // verify checksum
00079             if( intSum != sum.value() ) {
00080                 socket.writeInt( (int)( result = ECHK ) );
00081                 VERBOSEMSG( 2, ( "checksum status ( block=%d, %08X DOESN'T MATCH %08X )\n", 
00082                                   blocknum, intSum, sum.value() ) );
00083                 returnstatus = 1;
00084                 break;
00085             }
00086         }
00087 
00088         // received block and checksum matched
00089         // can write block to file now
00090         offset = bufsize * blocknum;
00091 
00092         fileMutex().lock();
00093         offset = lseek( fd, offset, SEEK_SET );
00094         len = write( fd, buffer, blocklen );
00095         fileMutex().unlock();
00096 
00097         if( len < blocklen ) {
00098             socket.writeInt( (int)( result = EWRT ) );
00099             returnstatus = 2;
00100             break;
00101         }
00102 
00103         // give client confirmation that everything is ok
00104         socket.writeInt( (int)( result = GOOD ) );
00105     } // for
00106 
00107     delete[] buffer;
00108 
00109     VERBOSEMSG( 3, ( "finished ( receiver=%2d, status=%d )\n", num, returnstatus ) );
00110 
00111     if( returnstatus != 0 ) {
00112         // on error cancel execution of all threads
00113         // and let sender get broken pipe from closed connection
00114         ::exit( returnstatus );
00115     }
00116 
00117     return (void*)returnstatus;
00118 }    

 


BaBar Public Site | SLAC | News | Links | Who's Who | Contact Us

Page Owner: Jacek Becla
Last Update: October 04, 2002