00001 /*MT* 00002 00003 MediaTomb - http://www.mediatomb.cc/ 00004 00005 io_handler_chainer.cc - this file is part of MediaTomb. 00006 00007 Copyright (C) 2005 Gena Batyan <bgeradz@mediatomb.cc>, 00008 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc> 00009 00010 Copyright (C) 2006-2010 Gena Batyan <bgeradz@mediatomb.cc>, 00011 Sergey 'Jin' Bostandzhyan <jin@mediatomb.cc>, 00012 Leonhard Wimmer <leo@mediatomb.cc> 00013 00014 MediaTomb is free software; you can redistribute it and/or modify 00015 it under the terms of the GNU General Public License version 2 00016 as published by the Free Software Foundation. 00017 00018 MediaTomb is distributed in the hope that it will be useful, 00019 but WITHOUT ANY WARRANTY; without even the implied warranty of 00020 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00021 GNU General Public License for more details. 00022 00023 You should have received a copy of the GNU General Public License 00024 version 2 along with MediaTomb; if not, write to the Free Software 00025 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. 00026 00027 $Id: io_handler_chainer.cc 2081 2010-03-23 20:18:00Z lww $ 00028 */ 00029 00031 00032 #ifdef HAVE_CONFIG_H 00033 #include "autoconfig.h" 00034 #endif 00035 00036 #include "io_handler_chainer.h" 00037 #include "exceptions.h" 00038 00039 using namespace zmm; 00040 00041 IOHandlerChainer::IOHandlerChainer(Ref<IOHandler> readFrom, Ref<IOHandler> writeTo, int chunkSize) : ThreadExecutor() 00042 { 00043 if (chunkSize <=0) 00044 throw _Exception(_("chunkSize must be positive")); 00045 if (readFrom == NULL || writeTo == NULL) 00046 throw _Exception(_("readFrom and writeTo need to be set")); 00047 status = 0; 00048 this->chunkSize = chunkSize; 00049 this->readFrom = readFrom; 00050 this->writeTo = writeTo; 00051 readFrom->open(UPNP_READ); 00052 buf = (char *)MALLOC(chunkSize); 00053 startThread(); 00054 } 00055 00056 void IOHandlerChainer::threadProc() 00057 { 00058 try 00059 { 00060 bool again = false; 00061 do 00062 { 00063 try 00064 { 00065 writeTo->open(UPNP_WRITE); 00066 again = false; 00067 } 00068 catch (TryAgainException e) 00069 { 00070 again = true; 00071 sleep(1); 00072 } 00073 } 00074 while (! threadShutdownCheck() && again); 00075 00076 bool stopLoop = false; 00077 while (! threadShutdownCheck() && ! stopLoop) 00078 { 00079 int numRead = readFrom->read(buf, chunkSize); 00080 if (numRead == 0) 00081 { 00082 status = IOHC_NORMAL_SHUTDOWN; 00083 stopLoop = true; 00084 } 00085 else if (numRead < 0) 00086 { 00087 status = IOHC_READ_ERROR; 00088 stopLoop = true; 00089 } 00090 else 00091 { 00092 int numWritten = 0; 00093 while (! threadShutdownCheck() && numWritten == 0 && ! stopLoop) 00094 { 00095 numWritten = writeTo->write(buf, numRead); 00096 if (numWritten != 0 && numWritten != numRead) 00097 { 00098 status = IOHC_WRITE_ERROR; 00099 stopLoop = true; 00100 } 00101 } 00102 } 00103 } 00104 } 00105 catch (Exception e) 00106 { 00107 log_debug("%s", e.getMessage().c_str()); 00108 status = IOHC_EXCEPTION; 00109 } 00110 try 00111 { 00112 if (threadShutdownCheck()) 00113 status = IOHC_FORCED_SHUTDOWN; 00114 readFrom->close(); 00115 writeTo->close(); 00116 } 00117 catch (Exception e) 00118 { 00119 log_debug("%s", e.getMessage().c_str()); 00120 status = IOHC_EXCEPTION; 00121 } 00122 }
1.6.1