Tuesday, May 24, 2011

Ubuntu: Network Manager is evil

Warning - this post if filled with hatred, if you believe in forgiveness, you may want to look away now.

In my book, the only sin worse than uselessness, is actively causing damage and waste of time.
What punishment ought to be meted then, to something that, having proven to be useless, causes untold waste of time.

Yes, NetworkManager, and nm-applet: I'm looking at you two.

Quite apart from never having quite understood what use one could have for either, I have found a number of situations in which NM has caused waste of time, only the last of which has been to prevent a KVM virtual machine I just created to connect to the network, despite all my efforts, searching on the Web, trying out countless variations on configurations and, yes, several reboots.

I have been following along the instructions given here, only to be unable to connect in UserMode, barely managing (via the Bridged interface) to connect to my host machine, and totally failing to obtain any connection to the outside world.

Enter

sudo apt-get purge network-manager network-manager-gnome

and, hey, presto, all is good and well, and I can happily connect from my guest OS to the Internet.
(see also here)

Simply changed my /etc/network/interfaces file to reflect my settings (YMMV, adjust to your LAN settings) and all works just fine:

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp

auto br0
iface br0 inet static
        address 192.168.1.10
        network 192.168.1.0
        netmask 255.255.255.0
        broadcast 192.168.1.255
        gateway 192.168.1.1
        bridge_ports eth0
        bridge_stp off
        bridge_fd 0
        bridge_maxwait 0

Just remember to restart the network after you have made the changes:

sudo /etc/init.d/networking restart


Die in pain, Network Manager, and may the world be a better place without you.

Sunday, May 22, 2011

Creating a C++ callback function from a class instance method


I have been playing around with the Boost library and, in particular, the boost::thread multithreading library.


There a thread is simply created by constructing an object of type boost::thread, and passing in to the constructor a pointer to the function to be executed in the newly spawned thread.


There is much more to it, and I encourage you to read the documentation, but that gave me an interesting opportunity to ponder the issue of how to create a thread by instead passing in a pointer to a class's method: the need typically arises when one does not want to use global variables (which need to be guarded against race conditions) or where parameters are necessary for the execution of the method and/or return values are expected.


Granted, the boost::thread constructor allows you to pass in up to nine parameters, so that's rarely an issue, but I just wanted to find out a reasonably general way to achieve this; it turns out that this is far from trivial, and I thought I'd share my findings.


For the impatient, this is the solution:

template<typename T, typename V, typename R>
class MakeCallback {

  // Member method in T(ype), takes parameter V(alue),
  // and returns an object of type R(esult)
  // Note the parentheses around (T::*): without them, 
  // the compiler gets confused.
  typedef R(T::*func)(const V&);
  func f_;
  T& t_;
  V value_;
  R* res_;
public:
  MakeCallback(T& type, func f, const V& value, R* res = NULL) :
      f_(f), t_(type), value_(value), res_(res) { }
  virtual ~MakeCallback() { }
  void operator()() {
    if (res_)
      // Note here the parenthesis around t_.*f_ 
      // They are necessary, or a compiler error will be generated
      *res_ = (t_.*f_)(value_);
  }

  // This allows the pointer to the result value to
  // be set after the object has been created
  void set_res(R* res) { res_ = res; }
};

and this is how one uses it:

int main(int argc, char[}* argv) {
  A a(33);
  int res;
  // Generally, you don't need the & operator to take a function's pointer.
  // But in this case it's mandatory, or the compiler will complain
  // about doSomething() not being static.
  // In any event, the use of & makes your intent clearer (you are taking
  // the method's address,
  // not invoking it) and I encourage you to use it consistently, even where
  // this is not stricly necessary.
  MakeCallback<>A, int, int> mc(a, &A::doSomething, 22, &res);
  boost::thread do_it(mc);
  do_it.join();
  std::cout << "And the result is : " << res << std::endl;

  B b;
  boost::thread another(MakeCallback<A, std::string, B>(a, &A::doSomethingElse, "22.13", &b));
  another.join();
  std::cout << "..and B is " << b.get() << std::endl;
}
given the following declarations for A and B:
class B {
  float x;
public:
  B(float s = 0.0) : x(s) {}
  float get() { return x; }
};

class A {
  int num_;
public:
  A(int num) : num_(num) { }

  int doSomething(const int& k) {
    return num_ + k;
  }

  B doSomethingElse(const std::string& s) {
    double b = ::atof(s.c_str()) + num_;
    return B(b);
  }
};
A couple of points that have caused me much head-scratching and I thought it worth passing on:
  • you must use the '&' operator in front of A::doSomething, or the compiler will complain about it not being a static function;
  • note we are, in fact, calling an instance method: in other words, we expect to have instance-specific values stored in the class (A in this case) that our method (doSomething()) will use
  • note also the use of a pointer (R* res_) to store the return value: this is important; without it, the return value of the method call ((t_.*f_)(value_)) will be lost!


    This is because, in the call to boost::thread(mc) the compiler automatically created a copy of our object (using the compiler-generated copy constructor; see Scott Meyer's "Effective C++", Item 5)
  • Note also the calls to thread::join() - without them, you'd have a race on the returned values: possibly reading them, before the actual method (doSomething()) had any chance of updating it;
Just to be clear, this rather trivial implementation is not meant to be used in real code (if you need something along these lines, boost::bind is what you want) but it was an interesting exercise in how to deal with generics, functors and callbacks.

Sunday, May 8, 2011

Skype on Ubuntu 10.04 - mic doesn't work

I got the following fix from here, but it does not tell the entire story:
(my setup: Acer Aspire One AO751h,
Ubuntu Lucid 10.04.2 LTS)




  •  
    I had the same problem on an Acer Timeline for a long time, but the balance trick works.


    Solution:
    A better way than changing the output balance is to use alsamixer or pavucontrol and mute one of the input channels. In alsamixer: F4 to change to recording, left/right to move to microphone, and z or c to mute one channel. In pavucontrol go to the "input devices" tab, unlock the channels, and mute one of the channels.


    It seems the normal volume control uses one balance slider for all inputs and outputs together. 

    The reality is that two poorly designed (and worse implemented) pieces of software interact in a way to make it virtually impossible for the average user to figure out what's going on:

    • Pulse Audio -- it still amazes me how a simple problem (enable audio on a PC) could be made so complicated and unusable;
    • Skype for Linux -- a real disgrace that a company of the might and power of Skype could let us down so badly: I just wish they had the decency of release the software open source, so we could fix it ourselves!
    Be that as it may, in addition to the 'fix' above, you need to also disable the "Allow Skype to adjust mixer levels" in the Sound Options tab of Skype - otherwise you can see skype continually adjusting your microphone's gain down until it gets to the point of being unaudible.

    Leaving it here for future reference: I don't expect Skype to fix this anytime soon!