Thursday, July 29, 2010

Porting ejpi: Tree Models in Qt

For me, one thing that differentiates the quality of a calculator on a mouse or touch driven device is having a calculation history and having it be interactive.  In Gtk I implemented this with a TreeView and a ListStore.  I had never implemented a custom model in Gtk, the included models were simple enough and flexible enough that I didn't have the need.

When I ported Gonvert to Qt, all I could find information for was custom models with QAbstractItemModel and QTreeWidget/QTreeWidgetItem.  QTreeWidgetItem's seem to only be good for Text.  This worked for parts of Gonvert but not for others so I went through the complicated affair of implementing a QAbstractItemModel.  I never felt like I fully understood the relationships of various items which usually worries me.  I also found it slow due to all of the protection I "should" have in my code which causes a lot of calling back and forth between C++ and Python.

I'm unsure how I missed it but when I started on ejpi I came across QStandardItemModel/QStandardItem.  This seems to at least allow a little more flexibility.  I can put icons and checkboxes in as well as text into the model.  I can also attach random python objects to each item.  The downside to a stock model is that you have to externally maintain any invariants but I was already managing those with my Gtk version.

I would be curious about the various performance merits to each approach but I'll have to pass on that for now.  The two main things I found frustrating was finding out about these and how each API was helpful in its own way, sometimes better, sometimes worse than its fellow approaches.

Most of my API issues were due to being unfamiliar with them and having to fight with the different approaches each model system took to presenting itself to the developer.  I still have one unfortunate piece of code in ejpi's calucation history which implements peek through a pop and a push.

I've not messed with setting the font on any of these (I should have for Gonvert and also for ejpi) so I'm unsure how the font experience is in Qt.  Mainly I'm interested in what formatting Pango html-esque tags allowed, changing relative size and basic formatting while keeping everything else to theme defaults.  A quick look through the API seems to suggest this is simple but that is yet to be determined.
I still miss GTK's generic way of handling rendering with its use of CellRenderers.  You don't have to be stuck with the built-in choices for representing items in your model.  It also keeps presentation information away from the model.

I did enjoy how easy QStandardItem's made user edits (sadly only seems to work on the desktop) and activating of individual items.  I didn't get around to exploring drag and drop for history re-arrangement (helpful for RPN calculators) but I don't think I implemented that for the GTK version either.

My GTK version and my Qt version of my ejpi history are available for comparison.

I guess the summary would be that overall I'm a fan of QStandardItemModel and wish I had found it sooner.

Porting ejpi: Icon Theming

ejpi includes some custom icons as well as using theme icons.

The custom icons are used for a couple of buttons.  I know the path to the custom icons and I load them up and everything works as expected.

The stock icons are used for deleting items in the calculator's history as well as a severity indicator and close button for the error info box.

I ported the GTK code from using theme icon names to QIcon.fromTheme.  It was fun for me to find out that fromTheme was added in Qt 4.6 (I still support Maemo 4.1 with my applications and it only has Qt 4.2 I think).  How did applications do this before 4.6?  I don't think I've used KDE since v2 but I think its generally supported icon theming along with everything else which precludes the application building all icons in as resources.

I also had fun with fd.o icon names not being available on all platforms so I had to find alternatives for each and put in fallback code.

I guess chock this up as another thing to abstract away when running on various platforms.

I'm not saying this was hard or anything but just another lessons learned in porting to Qt.

Saturday, July 17, 2010

"Antenna-gate", Fanboys, and Trolls

I just saw a good post on this from the Google Testing Bog.

Despite my dislike of Apple and their treatment of developers (and my disgust that developers are flocking to receive their flogging) I think we should be careful how we react to this.  Problems happen.  There is both good and bad to how Apple handled this. If we feel a bit annoyed in how they handled this we should have that same annoyance no matter the source rather than giving in to fanboy-ism

Do we look at this and think how much better our platform is but get annoyed when others point out the problems with our platform of choice?

This is a general problem whether it be long standing technology flamewars (VI is better btw), to religion, or to politics.  Sometimes the very nature of having two groups forms an automatic antagonism (see also George Washington's Farewell address).

I find Krister Stendahl's rules for religious understanding to be very applicable to all of these areas of our life:

  1. When you are trying to understand another religion, you should ask the adherents of that religion and not its enemies.
  2. Don't compare your best to their worst.
  3. Leave room for "holy envy."

Concurrently Beating a Dead Horse

Sometimes it seems like the horse is already dead but today I came across a fun article describing Erlang's concurrency model.  This is no surprise because Actors (along with STM) seems to be a favorite on the various programming sites.

So why continue the beatings?  I thought I'd solidify my thoughts by writing them out.  I also find exploring these principles beneficial for my projects to improve design even if the high level implementations wouldn't fit within the architecture for some of them.


In any concurrency discussion I think its good to remind ourselves of the pillars of concurrency to help avoid silver-bullet-syndrome.  I highly recommend Herb Sutter's Effective Concurrency series, especially the introductory article where he talks about Callahan's Pillars.
(sorry for the text image, that is how the content was stored in the original article)

STM

First two items of background.  The first is that I'm one of those odd people who enjoys the area where hardware and software meet.  The second is that my current job is in software for test and automation systems.  Having to warn customers about the possibility of Death and Dismemberment is not pleasant.

With those in mind I tend to worry more about how a system, pattern, architecture, whatever talks to the real world than how parallel it can get.  This leads me to dislike STM as my default model of concurrency to use because the world is not transactional.  If you have a program controlling a swinging arm of death, what does a revert mean?  One of Microsoft's researchers on STM.NET admits to this problem and many others (but again it does have its uses).

Dataflow

I enjoyed my experiences with digital design in college but at the moment it is not the field for me.  Also VHDL and Verilog leave much to be desired.

I find the idea of applying the natural concurrency of digital hardware to software fascinating.

In the industry I work in there is a popular data flow programming language.  For high level integration or large datasets it seems great to have the implicit parallelism.  I wonder how much parallelism it really gets with small data sets in simple applications.  The language has a couple draw backs to me for the projects I work on outside of work:
  • Single vendor (never a fan of lock-in)
  • Except for the clunky implementation of Events, it does not handle other concurrency models which a task might be better for.
  • Not designed well for general purpose programming situations
  • Even though some applications seem fast to write the environment feels like it hinders me.
Actors

Now on to actors.  I've always been a fan of the simple concept of handling concurrency through shared-nothing message-passing like Erlang.  I can easily conceptualize how this would work with hardware.  I enjoy the fact that each process is normally short-lived enough that the GC doesn't even need to be called.  These combine to give it soft real-time which is a field I've always found fascinating.

How does it handle various models of concurrency?  I like the idea of having access to an Actor's low level primitives in Erlang to more naturally implement something else like a finite-state-machine.  The low-level message passing is events so you get that.  I don't think I'm doing enough embarrassing parallel tasks to miss having dataflow.  I bet you could model a form of STM for groups of actors with the error system.

Sadly I've never really done anything in Erlang because:
  • At work when I do something in my language of choice I need to optimize for implementation time and not reduced run times which my investigation into Erlang seems to indicate it would be poor at. 
  • With my open source work it usually centers around another component for which I need to have a means of talking to.  Python has a lot of bindings.  I feel like with Erlang I'd have to roll my own.
Actors lose their appeal to me in other languages.  In Python the boilerplate and the overhead to achieve shared-nothing seems too much.  Maybe its just FUD but even in Scala it sounds unappealing.  This leads me to my last item

Events

Events aren't as high-level of a concurrency model as STM and Actors but they can sometimes have a lower barrier to entry, especially when integrating with certain frameworks.  Previously all of my open source applications have been glib based and most were GTK based.  I found glib events a pleasure to work with.

Simple UI callbacks work well.  I could simplify more complex sequences of callbacks like with DBus by abstracting them away but I've tended to abstract the concept so I can do things like map/reduce DBus calls.

Registering idle and timeout events seem to be atomic which makes life great certain applications of parallelism.  What I've tended to do is keep a thread for a group of data (like my connection state for Google Voice).  I then push to a queue a task I want the thread to apply to the data (make a GV call, get contacts, etc) and I include a callback that is registered as an idle callback for when the data is ready.  I have no management of locks to worry about.

I've even been able to abstract away the callbacks to keep good spatial locality on the logic in the code.

An example from The One Ring, my Telepathy Connection Manager for Google Voice:
    @misc_utils.log_exception(_moduleLogger)
    def RequestStreams(self, contactId, streamTypes):
        """
        For org.freedesktop.Telepathy.Channel.Type.StreamedMedia

        @returns [(Stream ID, contact, stream type, stream state, stream direction, pending send flags)]
        """
        contact = self._conn.get_handle_by_id(telepathy.constants.HANDLE_TYPE_CONTACT, contactId)
        assert self.__contactHandle == contact, "%r != %r" % (self.__contactHandle, contact)

        le = gobject_utils.AsyncLinearExecution(self._conn.session.pool, self._call)
        le.start(contact)


        streamId = 0
        streamState = telepathy.constants.MEDIA_STREAM_STATE_CONNECTED
        streamDirection = telepathy.constants.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL
        pendingSendFlags = telepathy.constants.MEDIA_STREAM_PENDING_REMOTE_SEND
        return [(streamId, contact, streamTypes[0], streamState, streamDirection, pendingSendFlags)]

    @misc_utils.log_exception(_moduleLogger)
    def _call(self, contact):
        contactNumber = contact.phoneNumber

        self.__calledNumber = contactNumber
        self.CallStateChanged(self.__contactHandle, telepathy.constants.CHANNEL_CALL_STATE_RINGING)

        try:
            result = yield (
                self._conn.session.backend.call,
                (contactNumber, ),
                {},
            )
        except Exception:
            _moduleLogger.exception("While placing call to %s" % (self.__calledNumber, ))
            return


        self._delayedClose.start(seconds=0)
        self.CallStateChanged(self.__contactHandle, telepathy.constants.CHANNEL_CALL_STATE_FORWARDED)

In the DBus callback (as in, happens in the main-loop) RequestStreams I create an AsyncLinearExecution object (eh, couldn't think of something better for a name) that runs the generator _call as an idle callback (again, executes in the main-loop).  The yield passes a function, args, and kwds to the thread passed into AsyncLinearExecution's __init__ for it to run without blocking the main-loop.  When it finishes it takes the results and passes that out of the yield.  I can even move the exception from the thread to be thrown at the yield.


I maintain AsyncLinearExecution as an object so I can "cancel" it at anytime.  My style of cancellation is for the thread's results to be ignored.   In the try/except this gets represented as a StopIteration exception.  This style of cancellation greatly simplifies my shutdown logic for a Telepathy Connection.

I've not read too much about other event based systems for Python but if they don't have a main-loop I scratch my head as to how they integrate with threading and other features.

In conclusion:
  • STM: Doesn't seem appropriate for any of my applications
  • Dataflow: Digital hardware is fun but not a fan of the main implementation in software
  • Actors: Cool but lack of integration with libraries limits my use of languages designed around it
  • Raw Events: a lot of fun for my open source applications.
I thought I'd also note that we have a fairly young wiki page that touches on threading for Python and one more specifically for PyQt applications.  I've done some work on them on hope to have more information to add to them later as I continue porting my applications to Qt.

Thursday, July 15, 2010

Porting ejpi: Custom Widgets in Qt

Because of my off-repeated distaste for making custom widgets unless needed, the pie menus for ejpi are my first real custom widget.  Learning to write custom widgets is the reason I chose to port ejpi.

I started off with the C++ pie menu code from Nokia's add-ons.  I ported it to Python (I doubt anyone would package the binary and making Python bindings available for Maemo any time soon).  While at it I simplified the code and made it more re-usable.

Qt Pie Menu Design Evolution

QtPieItem is the client-provided object to store everything related to a slice.  The two subclasses are QtPieAction and QtPieMenu.

QtPieMenu works well as a subclass of QtPieItem for when you want submenus but doesn't make sense with the parent QtPieMenu.  What does the weight, icon, and text mean?  Why not use composition instead?  Besides I don't even need sub-menus in my application.  So I dropped this (could easily be added later).

QtPieAction starts to look a lot like QAction.  I figured I could just use QActions for all of my slices with a wrapper to track the weight (slice weight / all slices weight gives the percentage of a circle a slice takes up).

Moving on to QtPieMenu...

The center of the menu and outside the menu cause a cancellation.  I like actions being connected to the center (one of these actions could be a cancel).  I also like to throw the mouse so I wanted an option for infinite outer radius.

Overall I was seeing there were several pieces of code in here that could be reused and built up to make several variants of Pie Menus, depending on what was wanted.  So I broke out pie locations (QPieFiling, basically the Model), rendering (QPieArtist, kind of like a View), and then the actual widget (QPieDisplay, QPieButton, QPieMenu).

This worked really well.  I do not use QPieMenu so oh well.  A QPieButton can have its representation set with a QActionPieItem.


When the QPieButton is clicked it shows a QPieDisplay that is filled up with delicious goodness.


Life Implementing a Custom Widget

This was actually a fairly pleasant experience.

With the original GTK version of ejpi I struggled to grab the current theme's colors but never was able to.  I followed Qt Pie Menu's example in grabbing colors and it actually worked!  There was one bug in the original C++ code, they used a "dark" for unselected text when "mid" is what is called for but luckily Qt actually had great documentation on when to use what color.

The other major challenge on the desktop I had was sizing.  The QtPieMenu only used sizeHint which gives a suggested default size for widgets.  For the buttons I wanted a minimum size of what is needed to draw the item with a suggested size of the client specified size.  I wanted to then listen to resizes and scale my box accordingly so the user would have button separators.

For this I overrode minimumSizeHint and resizedEvent.  I have the suspicion that widgets are supposed to implement sizeHint, minimumSizeHint, and maximumSizeHint rather than setting the sizes directly to leave it in the wisdom of the client to possibly bypass the hints by setting the actual minimum, actual, and maximum sizes.

    def minimumSizeHint(self):
        return self._buttonArtist.centerSize()

    @misc_utils.log_exception(_moduleLogger)
    def resizeEvent(self, resizeEvent):
        self.setButtonRadius(min(resizeEvent.size().width(), resizeEvent.size().height()) / 2 - 1)
        QtGui.QWidget.resizeEvent(self, resizeEvent)

When checking how things ran on Maemo I ran into a couple of strange issues.  So they wouldn't become modal I registered the menus as SplashScreen.  I think the hacking around modality of popups was what killed performance on my GTK version.

Unlike the GTK version I was getting the frost effect to the whole window minus the square around the pie. That provided quite an awkward look.  I didn't find anything for this so I just drop the round pies.

The other problem which is yet to be resolved is that if an edge button is selected the pie appears off-center from the user's click.  The odd part to me is even the middle buttons have the pie go partially off-screen so it must be some kind of how much is it off the screen.

You can find the source code for these pie menus in ejpi's git repo.

Monday, July 12, 2010

Porting ejpi: Dynamic Layouts with (Py)Qt

Previous and Future ejpi UI

The current ejpi layout does not seem very dynamic
In the history column an error info box may appear that you can click away (custom made, not the new one available in the latest versions of GTK).  The "Trigonometry" button brings up a Touch Selector for choosing which secondary keyboard you want visible.

Some problems with this layout:
  • Buttons are oddly shaped
  • The keys would have to be customized for portrait and landscape
  • Showing two keyboards would take up too much space in portrait mode
  • Not enough space left to increase the button text size
Below I created a mockup of the adjusted layout in portrait mode

Showing only one keyboard at a time will allow the buttons to be a bit nicer and gives more space for the history.  Switching the secondary keyboard was two clicks away.  With only one keyboard switches might be more frequent so we'll switch to tabs with icon representations for single click access (despite what I remember of the Maemo guidelines discouraging tabs).  Moving the Push key out makes it available when any keyboard is selected and reduces the need to specialize the keyboard layouts based on orientation.

We've not changed too much in terms of how dynamic the UI is.  The only change is on rotation we will need to switch the keyboards from being to the right of the history to being below the history.

Comparing GTK and Qt Layout systems

GTK's layout system centers around container widgets that provide holes for their children to populate.  Also the HBox are VBox are very static.  Their base class is either abstract or an interface so you have to actually swap out the class in the widget hierarchy to change between a horizontal and vertical layout.

The impression I have of Qt so far is that it separates out the concept of layout from the widget container.  A way to think of it is the widget is the canvas to draw on while the layout constrains the sizes and locations of the things to be drawn.  I actually removed a layout at one point and the widgets stayed visible and in the same location as before.  You can have layout hierarchies but the API  support for layouts is drastically limited as compared to widgets.  Also the separate widget and layout hierarchies can complicate things.

Implementing My Dynamic Layouts

Of course when I got started I didn't understand the difference between the way they did layouts.  I tried to implement everything as if it was GTK.  I had complex layout hierarchies that I was trying to swap out at run time.  It seems simple to change up a flat layout hierarchy but when you are trying to work off of an abstraction the API disparity between widgets and layouts increases the complexity.  I tried multiple approaches to get it all to work to no avail.

I might have come across one possible approach but I ran into the need to do some casting because the API returned QLayoutItem proxies rather than proxies for the derived class QHBoxLayout, etc.  With PyGTK I never had to worry about casting so when hitting it with PyQt I gave up in disgust at how nasty that feels in Python.  Please note that I am a C++ developer by trade and have no problems with it in C++.

It was when I finally connected how layouts work in Qt that I made some progress.  I would create intermediary widgets that I'd assign my layouts to.  I could then add/remove/show/hide them all I wanted without issue.  I think this is the way it was meant to be done.  I think one of the reasons I hit a wall with this as compared to others is my abhorrence for inheriting from QWidget.  In Gonvert I even changed part of my user experience because I could not access certain event information unless I inherited from the Qt widget.

Its kind of hard to do code samples without gutting my entire application and plopping it in here so I'll just provide one class and how it sets up its widget/layout hierarchy:

class QErrorDisplay(object):

    def __init__(self):
        self._messages = []

        icon = QtGui.QIcon.fromTheme("gtk-dialog-error")
        self._severityIcon = icon.pixmap(32, 32)
        self._severityLabel = QtGui.QLabel()
        self._severityLabel.setPixmap(self._severityIcon)

        self._message = QtGui.QLabel()
        self._message.setText("Boo")

        icon = QtGui.QIcon.fromTheme("gtk-close")
        self._closeLabel = QtGui.QPushButton(icon, "")
        self._closeLabel.clicked.connect(self._on_close)

        self._controlLayout = QtGui.QHBoxLayout()
        self._controlLayout.addWidget(self._severityLabel)
        self._controlLayout.addWidget(self._message)
        self._controlLayout.addWidget(self._closeLabel)

        self._topLevelLayout = QtGui.QHBoxLayout()
        self._topLevelLayout.addLayout(self._controlLayout)
        self._widget = QtGui.QWidget()
        self._widget.setLayout(self._topLevelLayout)
        self._hide_message()

    @property
    def toplevel(self):
        return self._widget

    ...

Note the toplevel property.  Kind of nasty but its what I use to insert this into the rest of the class hierarchy

        self._controlLayout = QtGui.QVBoxLayout()
        self._controlLayout.addWidget(self._errorDisplay.toplevel)
        self._controlLayout.addWidget(self._historyView.toplevel)
        self._controlLayout.addLayout(self._userEntryLayout)


Something else neat that I noticed is that in Qt, QHBoxLayout and QVBoxLayout are just used for convenience when working with QBoxLayout which dynamically supports switching from horizontal and vertical layouts.  This made me happy with Qt for once.  I can't imagine there being significance enough of a difference that they should be separate in GTK or if there is that a dynamically switchable layout couldn't be supported.  I can't speak too positively of Qt or people might worry.  I think its a disservice that Qt has QHBoxLayout and QVBoxLayout and recommends their usage.  Do you really need an extra class to not have to type in one extra parameter into the constructor?  Really?

        if maeqt.screen_orientation() == QtCore.Qt.Vertical:
            defaultLayoutOrientation = QtGui.QBoxLayout.TopToBottom
        else:
            defaultLayoutOrientation = QtGui.QBoxLayout.LeftToRight
        self._layout = QtGui.QBoxLayout(defaultLayoutOrientation)
        # Actual handling of rotation with setDirection not implemented yet


Conclusion

QVBoxLayout and QHBoxLayout are your enemy, QBoxLayout is your friend.

Attach layouts to QWidget's to make layout work easy.  It is sad that PyQt requires the use of casting.

I think there is suppose to be some new UI stuff to make dynamic layouts with fancy transitions easy.  As I will talk about when I discuss QTreeView's it is a bit annoying trying to figure out what is the recommended approach for what situation so I just went with (1) what I found documentation for and (2) what seemed familiar.

Porting ejpi from GTK t Qt

"e**(j * pi) + 1 = 0" is the more complete name of this project.  Throwing the "j" in their might be confusing but blame that on my engineering background.  Why yes, I love that fact that Python follows the EE notation over the Mathematical notation.

The idea for ejpi was born from reading a complaint on planet.gnome.org about how computer calculators overly mimic handheld calculators much to their detriment.  On a computer there are a lot more ways to interact with a program than a device with a one-line display and a fixed set of hardware buttons.

So ejpi is designed as an RPN calculator that has an interactive history.  You can delete item and duplicate items.  With a one-line calculator it is easy to forget where you are in a multistep calculation, so ejpi shows you not just the result but the equation that got you there.

A 4" device (n8x0) is limited on what all you can put on the screen and shrinking it down to 3.5" (n900) makes it even harder.  Making matters worse is that even if the device has a qwerty keyboard (n800 doesn't) its not well suited for math.  So I chose to experiment with pie-menus as the keyboard.  Typical pie-menus behave more like a context menu and have the middle of the pie be cancel.  I changed this up a bit to mimic my favorite keyboard for the Palm, MessagEase.  The pies are buttons that if you just click will perform the center's operation.  If you click-drag the pie will popup and then release in the direction of another symbol for it to perform that operation. 

There is a trade-off in how much of the pie's contents the button shows.  If you show too much then it is cluttered.  If you show too little then the user has to explore every button to know what operations are supported and where.

Sadly on Maemo devices, the performance of the pie menus is not what I would like which makes this more of a toy program.  I actually use the HP42 clone more than my own calculator

Unlike when I blogged about Gonvert, I am still working on the ejpi port.  I've got all the basic functionality working except switching keyboards.  I also plan on adding rotation support, directly editing history, some UI tweaks, and maybe one or two other things that crop up.  If the performance of the pies is better I might add an algebraic entry mode to make ejpi more widely appealing.

So far I plan to write about my experience in writing custom widgets for Qt, handling of dynamic layouts, and the various tree models.  We'll see what is left by the time I am finished.

Friday, July 09, 2010

Mordecai

In my previous post I quoted from The Church of Jesus Christ of Latter-day Saints's Articles of Faith.

We believe in being subject to kings, presidents, rulers, and magistrates, in obeying, honoring, and sustaining the law.
I wanted to clarify what this means for when those beliefs are in contradiction to the law that we are meant to sustain.

Some aspects of our belief are encouraged practices and precedence is given to local law, like how we bury the dead.  Others are essential but not contradictory like when laws require a civil marriage to be performed, couples have performed separately their civil marriage and their sealing of their marriage for time and all eternity.  Even though we see the Gospel as being essential to everyone's happiness and eternal salvation, we proselyte only in countries that legally allow it.

Mordecai, Daniel, Shadrach, Meschach, and Abed-nego are great examples for when the Kings and laws contravenes our right to worship.  Rather than rising up in rebellion, Mordecai and the people fasted, prayed, and petitioned the King.  Daniel, Shadrach, Meschach, and Abed-nego all broke the law but honorably faced the consequences of their decision to do that without losing faith.

Please note, these observations are mine alone and are not meant to represent any of the people I am quoting

True Leadership

Around the world last Sunday is marked as July 4th, well, as long as you use the Gregorian calendar.  For the United States it is the celebration of declaring independence from Great Britain.

One of the Articles of Faith that I adhere to is
We believe in being subject to kings, presidents, rulers, and magistrates, in obeying, honoring, and sustaining the law.

This was the focal point of a lesson someone gave recently and we talked a bit about what it means to obey, honor, and sustain the law.

Its amazing what effect the words we chose have on what others say and what we all think.  Someone slipped in a comment about "leaders".  Nothing outright was said but small feelings I got where the conversation led made me worry a bit for two reasons, 1) what are "leaders", and 2) how we view our "leaders".

For (1), as I quoted previously from Hugh Nibley
Leaders are movers and shakers, original, inventive, unpredictable, imaginative, full of surprises that discomfit the enemy in war and the main office in peace. For managers are safe, conservative, predictable, conforming organization men and team players, dedicated to the establishment.
...
For the manager, on the other hand, the idea of equality is repugnant and indeed counterproductive. Where promotion, perks, privilege, and power are the name of the game, awe and reverence for rank is everything, the inspiration and motivation of all good men.
How many of our representatives, executives, and judges are truly leaders?  Personally, it makes me feel dirty calling them "leaders".

Now for (2) which makes me feel even dirtier.  Reading Thomas Paine's comparison of representative governments to monarchical governments in "Rights of Men" has given me cause to reflect.  When reading how people view and treat the monarchical court's I wonder if in part we carried too much of that tradition with us and if we also in part reverted back to previous bad habits?

The elected and nominated officials are our representatives.  We are the United States government, not those people filled in their buildings in Washington.  They are our employees.  Yes, we would love for them to be leaders for that is what is needed to face the challenges they do.  Yes, we need to sustain them, but not as some lord or duke but as underlings that we are to empower and provide needed support and correction to.

Why is it that we use the Peter Principle and Dilbert Principle in offering "promotions"?

Why is it when we have two underlings vying for a promotion that we view it as a competition between the better of two evils? In business when there is no suitable internal candidate for a position, do we still higher one of the unsuitable ones or do we do take the risk of the unknown and perform an external hire to some third party?

Please note, these observations are mine alone and are not meant to represent any of the people I am quoting

Thursday, July 08, 2010

Trust Issues

Where I work we write in C++ but our coding style has been heavily influenced by kernel development and older coding practices.  This means we do not use exceptions, even in userspace.

Rather than using a global variable for errors or peppering our code with return value checks, we pass a reference to an error value into all of our functions.  On an incoming error, the function is suppose to be a no-op.

The group I work in is responsible for shared code by many hardware product teams.  One joys of this is when something a hardware group develops is wanted by others, we become the owners.  Its also fun when they continue to contribute features to it and we remain weak in our knowledge of it.  Oh and we are also clients of some groups that provide shared code for the whole company.

The group underneath us in the stack has had a bug with their tScopedLock code that it can cause a BSOD when an error is being passed in in an ISR.

The code looks something kind of like (changed for simplicity, especially to be free of internal code)

void tClass::operation(void* param, int& errno)
{
  tScopedLock lock(memberLock, errno);

  if(errno != 0)  {
    int tempError = 0;
    cleanup(param, tempError);
    return;
  }
  ...
}

Because we technically own the component they sent the bug report our way with a suggested fix that they tested.

void tClass::operation(void* param, int& errno)
{
  if(errno != 0)
  {

    return;
  }

  tScopedLock lock(memberLock, errno);


  if(errno != 0)  {

    int tempError = 0;
    cleanup(param, tempError);
    return;

  }
  ...

}


This seemed fishy to me.  One issue is the second error check only gets executed if the lock fails to acquire.  Seems like a small scope to worry about cleanup and that should be left for later.  The second is they probably had a reason to do that cleanup and do it under the lock.  I double checked with the implementer and he confirmed it would leak memory.  At least its better than a blue screen.


So my solution is found below.



void tClass::operation(void* param, int& errno)
{
  int tempError = 0;    tScopedLock lock(memberLock, tempError);


  if(errno != 0)   {

    cleanup(param, tempError);     return;

  }
  else
  {
    errno = tempError;
  }
  ...

}


All of the code is irrelevant.  Who introduced the problem and who made the fix isn't relevant.  To me the lesson here is the importance of code ownership (even if you don't know the code you own).  Our clients are under pressure to meet their deadlines and don't feel the same level of responsibility for this code.  It met their immediate needs and they moved on.  We release with them and so have the same deadline but with a smaller bug backlog.  Fair enough we do have a bit less stress.  I still think our ownership of the code helped us to ensure it had the proper quality for the release looming over us.

Another great example is we have code repos for "shared code" that have no owner.  Yes someone originally put it there but the ownership isn't recognized on the business side of things so when you have deadlines coming up it is hard to justify fixes or improvements.  We end up viewing it as the code graveyard.

I'm not saying any of this is novel.  I just think it was a nice clean example, one of those "huh, nice" type of things.