]> git.llucax.com Git - z.facultad/75.74/practicos.git/blob - practicas/pipi/src/devque.cpp
Cosas de Distribuidos I.
[z.facultad/75.74/practicos.git] / practicas / pipi / src / devque.cpp
1 #include "devque.h"
2 #include <cstring>
3 #include <unistd.h>
4 #include <fcntl.h>
5 #include <sys/types.h>
6 #include <sys/ipc.h>
7 #include <sys/msg.h>
8 #ifdef DEBUG
9 #include <iostream>
10 #endif
11
12 struct Frame
13 {
14     Dev::mac_type mac;
15     size_t size;
16     char frame[1];
17 };
18
19 DevQue::DevQue(mac_type mac, key_t key, size_t mtu)
20     throw (std::runtime_error, std::logic_error):
21         Dev(mac, mtu)
22 {
23     que_id = msgget(key, IPC_CREAT | 0666);
24     if (que_id == -1)
25         throw std::runtime_error("No se pudo crear la cola");
26 }
27
28 void DevQue::transmit(const std::string& data, const mac_type& mac)
29     throw (std::runtime_error, std::logic_error)
30 {
31 #ifdef DEBUG_TRACE
32     std::cout << "DevQue[" << que_id << "]::transmit()\n";
33 #endif
34     if (data.size() > mtu)
35         throw std::logic_error("Tamaño de datos mayor al MTU");
36     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
37     if (!f)
38         throw std::runtime_error("No se puede reservar memoria");
39     f->mac = mac;
40     f->size = data.size();
41     memcpy(f->frame, data.data(), data.size());
42     int res = msgsnd(que_id, f, mtu + sizeof(size_t), 0);
43 #ifdef DEBUG_QUE
44     std::cout << "DevQue[" << que_id << "]::transmit(msgtype/mac = "
45         << f->mac << ", size = " << f->size << ")\n";
46 #endif
47     free(f);
48     if (res == -1)
49         throw std::runtime_error("Error al poner en la cola");
50 }
51
52 std::string DevQue::receive() throw (std::runtime_error)
53 {
54 #ifdef DEBUG_TRACE
55     std::cout << "DevQue[" << que_id << "]::receive()\n";
56 #endif
57     return receive(mac);
58 }
59
60 std::string DevQue::receive(mac_type& mac) throw (std::runtime_error)
61 {
62 #ifdef DEBUG_TRACE
63     std::cout << "DevQue[" << que_id << "]::receive(mac)\n";
64 #endif
65     Frame* f = (Frame*) malloc(sizeof(Frame) + mtu);
66     if (!f)
67         throw std::runtime_error("No se puede reservar memoria");
68     int res = msgrcv(que_id, f, mtu + sizeof(size_t), mac, 0);
69     if (res == -1)
70     {
71         free(f);
72         throw std::runtime_error("Error al sacar de la cola");
73     }
74     std::string s((char*) f->frame, f->size);
75     if (mac == 0)
76         mac = f->mac;
77     free(f);
78 #ifdef DEBUG_QUE
79     std::cout << "DevQue[" << que_id << "]::receive(msgtype/mac = "
80         << mac << ", size = " << s.size() << ")\n";
81 #endif
82     return s;
83 }
84
85 /// Indica cuantos elementos hay en la cola
86 size_t DevQue::size() const
87 {
88     struct msqid_ds minfo;
89     msgctl(que_id, IPC_STAT, &minfo);
90     return minfo.msg_qnum;
91 }
92
93 /// Indica si está vacía la cola
94 bool DevQue::empty() const
95 {
96     return size() == 0;
97 }
98
99 // vim: set et sw=4 sts=4 :