Take the 2-minute tour ×
Code Review Stack Exchange is a question and answer site for peer programmer code reviews. It's 100% free, no registration required.

I'm coding a networking software, which has lots of functions (modules) which can be run in parallel. They share some resouces, like libnet_contexts of every type, pcap_handles, device info (may not change). Now the sructure is (pseudocode):

class Tools
{
    Libnet link;
    Libnet raw4;
    Libnet raw6;
    Pcap sniffer;
    Pcap router;

    std::mutex l_mutex; //link
    std::mutex r4_mutex; //raw4
    std::mutex r6_mutex; //raw6
    std::mutex s_mutex; //sniffer
    std::mutex r_mutex; //router

    //helpers
    bool GetNextHopMAC(uint src_ip, uint dst_ip, byte mac[6]);
    uint HostToIP(std::string hst);

public://methods which may run in parallel
    bool Init(std::string device);/* opening handles/contexts */
    bool Sniff(std::string filter, std::string ouputfile);
    bool SendARP(uint dst_ip, uint src_ip, byte dst_mac[6]);
    bool SendARP_Loop(std::string host1, std::string host2); //spoofing
    bool StartRouting(); //routes traffic
    /*and more*/
}

and in main (just an example):

int main()
{
    /*redirecting lazy brothers internet to learn math*/
    Tools tools;
    std::thread arps(&Tools::SendARP_Loop, &tools, "mybrother", "gateway");
    std::thread forw(&Tools::StartRouting, &tools);
    std::thread dnsh(&Tools::ReDNS, &tools, "math.com");
    arps.join();
    forw.join();
    dnsh.join();
    return 0;
};

It is working, but infinite locks can happen when a function never returns, in case of an loop, where the mutex locks the whole function (packet flooding).

What are better ways of doing this, supposing I am going to make a GUI for this too, how can I restructure the program so these methods can have different outputs (windows or text fields). Is creating a new context for the desired type (Libnet link for a SendARP) in methods and not having mutexes better?

share|improve this question

closed as off-topic by JaDogg, RubberDuck, tim, Simon André Forsberg, Gareth Rees Aug 26 '14 at 11:46

This question appears to be off-topic. The users who voted to close gave this specific reason:

  • "Questions must involve real code that you own or maintain. Questions seeking an explanation of someone else's code are off-topic. Pseudocode, hypothetical code, or stub code should be replaced by a concrete example." – JaDogg, RubberDuck, tim, Gareth Rees
If this question can be reworded to fit the rules in the help center, please edit the question.

    
Psuedocode or hypothetical code is off topic –  JaDogg Aug 26 '14 at 11:03
    
Not only are you explicitly saying that you are posting pseudocode, but it also seems like your code is not doing what you want it to do. –  Simon André Forsberg Aug 26 '14 at 11:27

1 Answer 1

I have no idea what Libnet and Pcap are, but it would look better in this case, rather than a mutex for every variable in class Tools, to have each object be thread-safe (with its own internal mutex if necessary to make it so).

For example, if a Libnet is not re-entrant and you need it to be, consider creating a wrapper:

class LibnetTS
{
    Libnet obj;
    std::mutex mutex; 

  public:
    // access methods
};

// similarly PcapTS

class Tools
{
    LibnetTS link;
    LibnetTS raw4;
    LibnetTS raw6;
    PcapTS sniffer;
    PcapTS router;

public:
    // methods
};

You'd get deadlock if any method holds one mutex whilst waiting for another and this happens in a circular way. e.g. if one thread holds l_mutex waiting for r_mutex and another thread is doing the reverse.

What is it that causes your 3 methods to end? There must be something that tells your system to shutdown. All threads need to be wakeable on a shutdown.

If they run in infinite loops, they need to check each time they loop whether a shutdown has been invoked.

If the infinite loop includes a blocking call, it needs to be "wakeable" by the shutdown event. This can be done in many ways:

  • A condition variable that is broadcast to when this occurs. If there are many condition variables about for your threads, each one needs to be signalled or broadcast.

  • The blocking condition timing out periodically and then before you wait again, check if there is a shutdown. This has the disadvantage of having to wait until the next timeout rather than exiting immediately.

  • Some kind of "quit" message being posted to whatever queue your thread is waiting on. Slightly different to the condition variable broadcast as it is received as an actual item to process.

share|improve this answer
    
most methods has infinite loops in them, but some are only linear functions. Libnet and Pcap are networking apis, helps sending packets over the net, or catching packets. Libnet variables has an internal context, so concurrent access is not allowed. –  pndev Aug 26 '14 at 10:41

Not the answer you're looking for? Browse other questions tagged or ask your own question.