Advertisement
Guest User

Untitled

a guest
Jan 16th, 2019
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.13 KB | None | 0 0
  1. #include <iostream>
  2. #include <string>
  3. #include <thread>
  4.  
  5. #define PIPE_BUF 64 //bufor wszystkich pipe'ów
  6. #define PIPE_SIZE 64 //ilość bitów w jednym pipe
  7.  
  8. struct process {
  9.     int id;
  10.     int parent = 0;
  11. };
  12.  
  13. class communicationModule {
  14.  
  15. private:
  16.  
  17.     struct pipe_inode_info {
  18.         char data[PIPE_SIZE];
  19.         process sender;
  20.         process receiver;
  21.         bool lock = 0;
  22.         int dataSize = 0;
  23.     };
  24.  
  25.     struct arrayPipes {
  26.         pipe_inode_info canal;
  27.     };
  28.  
  29.     arrayPipes streamArr[PIPE_BUF];
  30.  
  31.     int arrayPos = 0;
  32.  
  33.     int addToArray(pipe_inode_info f, pipe_inode_info s) {
  34.         if (arrayPos + 1 > PIPE_BUF) {
  35.             std::cout << "BLAD! Przekroczono maksymalny rozmiar bufora!\n";
  36.             return -1;
  37.         }
  38.  
  39.         arrayPipes p, r;
  40.  
  41.         p.canal = f;
  42.         r.canal = s;
  43.  
  44.         streamArr[arrayPos] = p;
  45.         streamArr[arrayPos + 1] = r;
  46.  
  47.         arrayPos += 2;
  48.         return arrayPos - 1;
  49.     }
  50.  
  51.     void delFromArray() {
  52.         arrayPos -= 2;
  53.     }
  54.  
  55.     void returnStream(int p, pipe_inode_info &f, pipe_inode_info &s) {
  56.  
  57.         f = streamArr[p].canal;
  58.         s = streamArr[p + 1].canal;
  59.     }
  60.  
  61.     int checkReader(int p, process r) {
  62.         if (streamArr[p].canal.receiver.id == r.id) return 1;
  63.         else return 0;
  64.     }
  65.  
  66.     int checkWriter(int p, process w) {
  67.         if (streamArr[p].canal.sender.id == w.id) return 1;
  68.         else return 0;
  69.     }
  70.  
  71. public:
  72.  
  73.     ~communicationModule() {
  74.  
  75.     }
  76.  
  77.     communicationModule() {
  78.  
  79.     }
  80.  
  81.     int pipe(int(&fd)[2], process s, process r) {
  82.  
  83.         pipe_inode_info node1;
  84.         pipe_inode_info node2;
  85.  
  86.         for (int n = 0; n < PIPE_SIZE; n++) {
  87.             node1.data[n] = 0;
  88.             node2.data[n] = 0;
  89.         }
  90.  
  91.         node1.receiver = r;
  92.         node1.sender = s;
  93.         node2.receiver = s;
  94.         node2.sender = r;
  95.  
  96.         int state = addToArray(node1, node2);
  97.         int state2 = addToArray(node2, node1);
  98.  
  99.         if (state == -1 || state2 == -1) {
  100.             std::cout << "BLAD! ENFILE - brak miejsca w tablicy!\n";
  101.             return -1; //ENFILE (brakuje miejsca w systemowej tablica plikow)
  102.         }
  103.        
  104.         fd[0] = state;
  105.         fd[1] = state2;
  106.  
  107.         return 0;
  108.     }
  109.  
  110.     int read(int fd, std::string* buf, int count, process reader) {
  111.  
  112.         std::cout << "Proces " << reader.id << " odczytuje " << count << " znakow\n";
  113.  
  114.         while (streamArr[fd].canal.data[0] == 0) { std::this_thread::sleep_for(std::chrono::seconds(1)); }
  115.  
  116.         switch (checkReader(fd, reader)) {
  117.         case 1: {
  118.             int &dataSize = streamArr[fd].canal.dataSize;
  119.  
  120.             if (count <= dataSize) {
  121.                 while (streamArr[fd].canal.data[0] != 0 && count > 0) {
  122.                     *buf += streamArr[fd].canal.data[0];
  123.                     for (int n = 0; n < PIPE_SIZE - 1; n++) {
  124.                         streamArr[fd].canal.data[n] = streamArr[fd].canal.data[n + 1];
  125.                     }
  126.                     count--;
  127.                     dataSize--;
  128.                 }
  129.                 for (int n = dataSize; n < PIPE_SIZE; n++) {
  130.                     streamArr[fd].canal.data[n] = 0;
  131.                 }
  132.                 return buf->size();
  133.  
  134.             }
  135.             else if (count > dataSize) {
  136.                 while (streamArr[fd].canal.data[0] != 0 && count > 0) {
  137.                     *buf += streamArr[fd].canal.data[0];
  138.                     for (int n = 0; n < PIPE_SIZE - 1; n++) {
  139.                         streamArr[fd].canal.data[n] = streamArr[fd].canal.data[n + 1];
  140.                     }
  141.                     count--;
  142.                     dataSize--;
  143.                 }
  144.                 for (int n = dataSize; n < PIPE_SIZE; n++) {
  145.                     streamArr[fd].canal.data[n] = 0;
  146.                 }
  147.                 return buf->size();
  148.  
  149.             }
  150.         }
  151.  
  152.         case 0: { std::cout << "BLAD! Brak uprawnien do zapisywanie w potoku!\n"; }
  153.         }
  154.         //else error
  155.  
  156.     }
  157.  
  158.     int write(int fd, std::string buf, process writer) {
  159.         if (streamArr[fd].canal.lock == 1) {
  160.             std::this_thread::sleep_for(std::chrono::seconds(1));  std::cout << "Blokada\n";
  161.         }
  162.  
  163.         std::cout << "Proces " << writer.id << " wysyla komunikat o tresci " << buf << "\n";
  164.  
  165.         if (streamArr[fd].canal.sender.id == NULL) {
  166.             std::cout << "BLAD! EBADF - fd nie jest deskryptorem\n";
  167.             return -1;
  168.         } //EBADF (fd nie jest deskryptorem)
  169.         if (streamArr[fd].canal.receiver.id == NULL) {
  170.             std::cout << "BLAD! EPIPE - brak czytelnikow\n";
  171.             return -1;
  172.  
  173.         } //EPIPE (nie ma czytelnikow i lacze jest zablokowane lub nie ma w nim miejsca) /+ wysłanie sygnału SIGPIPE do procesu
  174.         if (streamArr[fd].canal.lock == 1) {
  175.             std::cout << "BLAD! EPIPE - lacze jest zablokowane\n";
  176.             return -1;
  177.         } //EPIPE (nie ma czytelnikow i lacze jest zablokowane lub nie ma w nim miejsca)
  178.  
  179.        
  180.  
  181.         int insertCount = 0;
  182.         switch (checkWriter(fd, writer)) {
  183.         case 1: {
  184.             streamArr[fd].canal.lock = 1;
  185.             int &dataSize = streamArr[fd].canal.dataSize;
  186.             if (buf.size() <= PIPE_SIZE - dataSize) {
  187.                 for (int n = dataSize, m = 0; n < PIPE_SIZE, m < buf.size(); n++, m++) {
  188.                     streamArr[fd].canal.data[n] = buf[m];
  189.                     dataSize++;
  190.                     insertCount++;
  191.                 }
  192.                 streamArr[fd].canal.lock = 0;
  193.                 return insertCount;
  194.             }
  195.             else if (buf.size() > PIPE_SIZE - dataSize) {
  196.  
  197.                 //if (spacLeft == 0) zwrocenie bledu EAGAIN
  198.  
  199.                 int m = 0;
  200.                 for (int n = dataSize, m = 0; n < PIPE_SIZE, m < buf.size(); n++, m++) {
  201.                     streamArr[fd].canal.data[n] = buf[m];
  202.                     insertCount++;
  203.                 }
  204.                 dataSize = PIPE_SIZE;
  205.  
  206.                 streamArr[fd].canal.lock = 0;
  207.                 //zamrożenie procesu
  208.                 return insertCount;
  209.             }
  210.             streamArr[fd].canal.lock = 0;
  211.         }
  212.  
  213.  
  214.         case 0: {
  215.             std::cout << "BLAD! EINVAL - fd nie jest dekstryptorem, do ktorego mozna pisac\n";
  216.             return -1; //EINVAL (fd nie jest deskryptorem, do ktorego mozna pisac)
  217.         }
  218.         }
  219.     }
  220.  
  221.     void printPipe(int fd) {
  222.         std::cout << streamArr[fd].canal.receiver.id << " < ";
  223.         for (int n = 0; n < PIPE_SIZE; n++) {
  224.  
  225.             if (streamArr[fd].canal.data[n] == 0) std::cout << '-';
  226.             else std::cout << streamArr[fd].canal.data[n];
  227.         }
  228.         std::cout << " < " << streamArr[fd].canal.sender.id << '\n';
  229.     }
  230.  
  231.     bool checkMessage(int fd) {
  232.         if (streamArr[fd].canal.data[0] == 0) return 0;
  233.         return 1;
  234.     }
  235. };
  236.  
  237. void readPipe(communicationModule* cm, int fd, std::string* bufor, process p) {
  238.     while (1) {
  239.         if (cm->checkMessage(fd)) {
  240.  
  241.             cm->read(fd, bufor, 8, p);
  242.             std::cout << "Proces " << p.id << " odczytal wiadomosc. Obecny bufor: " << *bufor << "\n";
  243.         }
  244.         std::this_thread::sleep_for(std::chrono::seconds(1));
  245.     }
  246. }
  247.  
  248.  
  249. int main() {
  250.     communicationModule cm;
  251.     process p1, p2;
  252.     p1.id = 1;
  253.     p2.id = 2;
  254.     p2.parent = 1;
  255.     int fd[2];
  256.     std::string buf;
  257.     std::string* b = &buf;
  258.  
  259.     cm.pipe(fd, p1, p2);
  260.     cm.write(fd[1], "test", p1);
  261.     cm.printPipe(fd[1]);
  262.     cm.read(fd[1], b, 4, p2);
  263.     getchar();
  264. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement