Página principal   Módulos   Lista de namespaces   Hierarquia de classes   Lista de componentes   Lista de ficheiros   Membros do namespace   Componentes membro   Ficheiros membro   Páginas relacionadas  

mensageiro_impl.H

Ir para a documentação deste ficheiro.
00001 
00007 #include <typeinfo>
00008 #include <sstream>
00009 #include <cerrno>
00010 
00011 #include <Utilitarios/cadeia.H>
00012 
00013 // Erro:
00014 inline IPC::Erro::Erro(std::string const& mensagem) 
00015     : Erros::Erro(mensagem) 
00016 {
00017 }
00018 
00019 inline IPC::Erro::Erro() 
00020     : Erros::Erro(std::string("Erro IPC: \"") + strerror(errno) + '"') 
00021 {
00022 }
00023 
00024 // Mensageiro:
00025 
00026 inline std::string IPC::Mensageiro::meuIdentificador() const
00027 {
00028     using namespace Utilitarios;
00029 
00030     passwd* info = getpwuid(meu_UID);
00031     return std::string(info->pw_name) + " (" + meu_PID + ')';
00032 }
00033 
00034 inline std::string IPC::Mensageiro::identificadorDoOutro() const
00035 {
00036     using namespace Utilitarios;
00037 
00038     passwd* info = getpwuid(UID_do_outro);
00039     return std::string(info->pw_name) + " (" + PID_do_outro + ')';
00040 }
00041 
00042 inline void IPC::Mensageiro::leMensagem()
00043 {
00044     tipo_dos_dados = leBasico(meu_PID);
00045     mensagem = leBasico(meu_PID);
00046 }
00047 
00048 template <typename Tipo>
00049 inline Tipo const IPC::Mensageiro::mensagemLida() const
00050 {
00051     if(typeid(Tipo).name() != tipo_dos_dados)
00052         throw Erro("Conversão de mensagem de " + tipo_dos_dados + " para " + 
00053                    typeid(Tipo).name() + " impossível!");
00054     
00055     std::istringstream entrada(mensagem);
00056     Tipo valor;
00057     entrada >> valor;
00058     if(not entrada.good() and not entrada.eof())
00059         throw Erro("Problema na extracção da mensagem!");
00060 
00061     return valor;
00062 }
00063 
00064 // Especialização, para evitar que a cadeia devolvida contenha apenas a
00065 // primeira palavra da mensagem:
00066 template <>
00067 inline std::string const IPC::Mensageiro::mensagemLida<std::string>() const
00068 {
00069     if(typeid(std::string).name() != tipo_dos_dados)
00070         throw Erro("Conversão de mensagem de " + tipo_dos_dados + " para " + 
00071                    typeid(std::string).name() + " impossível!");
00072     
00073     return mensagem;
00074 }
00075 
00076 template <typename Tipo>
00077 inline void IPC::Mensageiro::envia(Tipo& mensagem) const
00078 {
00079     std::ostringstream saida;
00080     saida << mensagem;
00081     
00082     if(not saida.good())
00083         throw Erro("Problema ocorreu durante a inserção da mensagem!");
00084 
00085     escreveBasico(PID_do_outro, typeid(Tipo).name());
00086     escreveBasico(PID_do_outro, saida.str());
00087 }
00088 
00089 template <typename Tipo>
00090 inline void IPC::Mensageiro::envia(Tipo const& mensagem) const
00091 {
00092     std::ostringstream saida;
00093     saida << mensagem;
00094     
00095     if(not saida.good())
00096         throw Erro("Problema ocorreu durante a inserção da mensagem!");
00097 
00098     escreveBasico(PID_do_outro, typeid(Tipo).name());
00099     escreveBasico(PID_do_outro, saida.str());
00100 }
00101 
00102 template <typename Char>
00103 inline void IPC::Mensageiro::envia(Char const*& mensagem) const
00104 {
00105     envia(std::basic_string<Char>(mensagem));
00106 }
00107 
00108 template <typename Char>
00109 inline void IPC::Mensageiro::envia(Char const* const& mensagem) const
00110 {
00111     envia(std::basic_string<Char>(mensagem));
00112 }
00113 
00114 template <typename Char>
00115 inline void IPC::Mensageiro::envia(Char* const& mensagem) const
00116 {
00117     envia(std::basic_string<Char>(mensagem));
00118 }
00119 
00120 template <typename Char>
00121 inline void IPC::Mensageiro::envia(Char*& mensagem) const
00122 {
00123     envia(std::basic_string<Char>(mensagem));
00124 }
00125 
00126 template <typename Char, int dimensao>
00127 inline void 
00128 IPC::Mensageiro::envia(Char const (& mensagem)[dimensao]) const
00129 {
00130     envia(std::basic_string<Char>(mensagem));
00131 }
00132 
00133 inline int IPC::Mensageiro::leBasicoInt(int const tipo, 
00134                                         bool const deve_esperar) const
00135 {
00136     std::istringstream entrada(leBasico(tipo, deve_esperar));
00137 
00138     int valor;
00139     entrada >> valor;
00140 
00141     if(not entrada.good() and not entrada.eof())
00142         throw Erro("Problema na extracção da mensagem!");
00143 
00144     return valor;
00145 }
00146 
00147 inline void IPC::Mensageiro::escreveBasicoInt(int const tipo, int const valor) 
00148 {
00149     std::ostringstream saida;
00150 
00151     saida << valor;
00152 
00153     if(not saida.good())
00154         throw Erro("Problema ocorreu durante a inserção da mensagem!");
00155 
00156     escreveBasico(tipo, saida.str());
00157 }
00158 
00159 inline void IPC::Mensageiro::estabeleceCaixaDoCorreio(key_t const chave)
00160 {
00161     /* Usa-se por omissão o getuid() para que a comunicação entre utilizadores
00162        não seja possível, eliminando-se assim muitos problemas. */
00163     int permissoes = (chave == key_t(getuid()))? 0660 : 0666;
00164 
00165     // Criação de caixa do correio/obtenção de identificador de caixa
00166     // do correio existente:
00167     identificador_da_caixa_do_correio = msgget(chave, IPC_CREAT | permissoes);
00168     if(identificador_da_caixa_do_correio == -1)
00169         throw Erro();
00170 }
00171 
00172 inline void IPC::Mensageiro::removeCaixaDoCorreio()
00173 {
00174     msgctl(identificador_da_caixa_do_correio, IPC_RMID, 0);
00175 }
00176 
00177 inline void IPC::Mensageiro::entraEmAcessoExclusivo() const
00178 {
00179     sembuf vermelho = {0, -1, 0};
00180     
00181     if(semop(identificador_do_semaforo, &vermelho, 1) == -1)
00182         throw Erro();
00183 }
00184 
00185 inline void IPC::Mensageiro::saiDeAcessoExclusivo() const
00186 {
00187     sembuf verde = {0, 1, 0};
00188     
00189     if(semop(identificador_do_semaforo, &verde, 1) == -1)
00190         throw Erro();
00191 }
00192 
00193 inline bool IPC::Mensageiro::cumpreInvariante() const
00194 {
00195     return meu_PID == int(getpid()) and meu_UID == int(getuid()) and
00196         0 <= identificador_da_caixa_do_correio and
00197         0 <= identificador_do_semaforo;
00198 }

Gerado em Tue Dec 3 15:19:35 2002 para Pacotes por doxygen1.3-rc1