- Feature Articles
- CodeSOD
- Error'd
- Forums
-
Other Articles
- Random Article
- Other Series
- Alex's Soapbox
- Announcements
- Best of…
- Best of Email
- Best of the Sidebar
- Bring Your Own Code
- Coded Smorgasbord
- Mandatory Fun Day
- Off Topic
- Representative Line
- News Roundup
- Editor's Soapbox
- Software on the Rocks
- Souvenir Potpourri
- Sponsor Post
- Tales from the Interview
- The Daily WTF: Live
- Virtudyne
Admin
Welcome Mr. Chen.
You can always tell a guy's first day on the job. This WTF is in early!
Admin
He's very punctual too. Every day at 7:00 AM exactly, his time, there's a new blog post. ; - )
Admin
Alex must be Sleep()ing in right now.
Admin
Since Alex is on vacation this week, the main forum is fed by an auto-pilot script. Stay tuned, folks, we'll see contributions from a lot of very interesting guest authors this week.
Admin
...wait a minute....
Admin
Regarding "The Daily WTF Reader Survey (tm)", can anyone tell me the difference between a "Programmer/Developer I" and a "Programmer/Developer IV"... just so I can decide which I am!
Oh, and assuming this survey is being used to decide what types of advertising we get on the site, what do people reckon I should choose to get more table football/beanbag girl type ad's? :-)
Admin
Classic WTF: reinventing the wheel in the stupidest way possible.
Admin
Actually this idiom is neither uncommon nor invalid on platforms that lack a directly-coded sleep() equivalent, and I'll bet the programmer came from such an environment. That's no excuse for doing absolutely nothing in the error cases, though, and having it exit the thread is just WTF, but the basic idea isn't crazy.
Admin
Programmer/Developer I would basically be a guy with less experience who handles the less complex tasks, and a P/D IV would be akin to a senior developer or technical lead in my opinion -- the go-to guy with the knowledge, experience, and (usually) can help you if you're having a problem. That is, those that don't end up on TDWTF themselves.
Admin
This isn't the dumb way to do it! Why, it looks positively Enterprisey(TM)(R)(WTF)!
Far more impressive than some stupid call to a boring function like sleep().
Admin
Generally 3-5 years of experience at each level, so if you have 9-10 years of experience, you're either at the high end of II or the low end of III.
Lead software developers are usually directly responsible for the success of one project, and chief software developers for several simultaneously.
I think the purpose of the survey is to see if they should do job postings here.
Admin
Could be worse; I've seen more than one programmer who, when tasked to do something like "wait 5 seconds", writes this code or similar:
DateTime end = DateTime.Now.AddSeconds(5);
while(end < DateTime.Now) {
for (int ii = 0; ii < 100000; ii++) { }
}
It has all the beauty of ignoring something like Sleep, *and* will spike the CPU to 100% for however long it's waiting for.
Admin
Maybe he needed a more accuracy than the 10ms resolution Sleep() provides?
Admin
Yes! I've seen this many, many times. I've tried to explain that this makes the code unstable. It's like talking to a really dumb rock. (In all fairness, sometimes you don't have "sleep".) It just inserts a race condition. How do you know if it's always going to be 6 seconds?
Will you pause for long enough?
Will you crash?
Will your compiler optimise out the loop that has nothing in it?
Who knows? It works now; ship that mofo!
Admin
I have to confess that I did almost exactly this, when I first learned VB. I was in high school at the time, if that makes it more acceptable..
Although, shouldn't it be "while(DateTime.Now < end) {" instead?Admin
Admin
Good pull kip.
And my favorite implementation of this so far was where the program would execute some external program (I think it might have been a batch file) and wait for the external dude to finish before resuming the program. The external program would basically sleep for 5 seconds, and then exit. Well...not always.
Admin
Uhh, I guess someone forgot about maybe doing this
Thread.Sleep()
Admin
I can't believe no one has yet pointed out that the code leaks the waitable timer if it succeeds!
Admin
The real danger here is that if you are running on a Xell 2600 without a BIOS patch (must be a MS problem<-> must be a Xell problem), and the system clock stops advancing while you are in this loop, you will burn 100% of the CPU for a long time.
Homework: Devise a "health check" that can determine if the system clock has stopped.
Hint: Have an external system provide a hearbeat.
Note: We switched back to HP servers.
Admin
Maybe they want 60 seconds to the exact microsecond. hmm no.
This is bad code though because it sounds as if the 60 seconds has been selected because it avoids some contention problem.
The handle is only closed if the handle failed to open - there is no cleanup (even though the exitthread is likely to take care of it).
Admin
The real WTF here isn't the lack of using Sleep, nor the bug where the hTimer handle isn't closed. The problem is that this function exists at all. Why would you want to wait for 60 seconds, and then exit the thread?! This stinks of a hack to fix an exit race condition. They probably weren't synchronizing the threads properly, and during the shutdown of the app, objects were being destroyed in the wrong order (because threads were exiting in the wrong order). So, what to do? I know, sleep the main thread for 60 seconds and THEN exit! That should be plenty of time for the child threads to exit...
Yes, Sleep(60000) followed by ExitThread(0) is definitely better, but I suspect that this function shouldn't exist in the first place. No matter how you code this function, it is still a WTF.Admin
Wow. I'm pretty sure the system clock stopping would break a *lot* of code...
Captcha: craptastic. It's like the captcha can read my mind!
Admin
The difference is about $50 -$100 K a year.
If you're under $50K, you're a 'I'. If you're over $100K, you're a 'IV'
Is it just me, or is Foosball girl looking extra perky today?
Admin
Finally, a real code WTF.
On Unix systems, it's not uncommon to see the select(2) system call as a portable version of sleep() (it even works on Windows). Not so common nowadays as way back in the day.
But the real WTF (you didn't think you would get away that easily?) here is that the thread needs a time delay before exiting. If you're writing multithreaded code that depends on timeouts to make sure things are working correctly, your code is already a WTF. This is the kind of code that breaks when the system is under heavy load, or when someone tries it on an SMP machine. If the thread was not ready to exit, it should not exit. If it doesn't know whether it can safely exit or not, waiting a certain amount of time will not make a difference.
Admin
Sorry, beat you to it my half an hour. But I'm glad that we are in agreement!
Admin
What happens in 2038 when end < now ?
Admin
Um, what is the Now() equivalent on a C64? Just curious because I always found it hard to work up such timers on a system that had no concept of time structures nor even possessed a real time clock.
CAPTCHA: truthiness - Perfect for this comment.
Admin
Then we wait......
Admin
That sounds like a *nix problem to me. Well, some Windows programs will have that problem, too, but .NET programs shouldn't (but I don't put anything past people who went to WTFU).
DateTime
won't overflow until 10,000, and the abstraction makes it possible to extend the range without breaking a lot of code (it would lead to a lot of serialization/parsing problems, though).Admin
And I beat you by an hour. ;)
We all agree that the code is bad - not by design, but by existence - then we're all thinking the right thing. If this was a perfect implementation, it would still be a WTF. Delays don't fix problems. They hide them. (Yes, there are valid reasons for waiting. This is not one of them.)
Admin
Admin
I feel the shame... :)
This is why people who don't know proper threading techniques shouldn't code in a multithreaded environment. Its kind of funny how most people say things like "OMG! Just use sleep!!!!" or "Haha! He's not cleaning up the timer handle". Those aren't the WTFs here. Yeah, they are silly, or a bug, but not really WTFs.
Admin
On a C64 it was OK to use a busy loop to do timing. There was no threading, other than what you implemented, so the processor had nothing else to do. Interrupts were minimally supported so possibly you could have used the sound device. That was handled by a special purpose chip so you could play music while the 6502 processor did something else.
Admin
This is a great WTF. First of all, you get the little WTFs of him not cleaning up the handles and such. Then you get the slightly larger WTF of him reinventing the wheel when you could just call sleep(). Then you get the ultimate WTF of him trying to fix a race condition, by sleep()ing.
This WTF is indeed, Brillant ;)
Admin
Admin
Besides which select() has better resolution than sleep() on many systems (which is a WTF in and of itself). Don't ask how I know - I spend to much time in !sleep() state
Captcha quality (oxymoron wtf?)
Admin
Commodore 64 *does* have a real time clock. It doesn't record date, though, and it's not battery-backed-up.
You can pull its value from BASIC variable TI$. I have no idea how to read it via machine language, but I seem to remember there was a KERNAL call for that. (I wonder what RDTIM does, maybe it does something related. =)
And in case you're curious: If your system doesn't have a RTC, you probably have other sources of constantly-updating things. If C64 didn't have a RTC, I'd probably hook something to the raster interrupt (Just update your second counter every 25th screen update, or something... I've done a raster interrupt thing only once so I can't remember when or how the stuff works) or via some other clock chip (C64 has CIA chips, which have programmable timer interrupts, I think).
Admin
Oh yeah?
PRINT TI$
000018
READY.
TI$="232729"
READY.
PRINT TI$
232735
READY.
Admin
Wow, this may be the first time that two or more programmer have agreed about a non-trivial issue on this site. And I totally missed both of your posts. It's nice to see a good WTF bringing people together against its creator.
Admin
Now THAT is funny!
:-)
Admin
Admin
The latter is fed intravenously.
Admin
Admin
Admin
And in the BASIC code which made the form so popular, the $TIME or $TI was a measure of clock ticks since start up, so anyone who turned their computer off each night or for any other reason restarted on a near-daily basis, that wouldn't be a problem.
Admin
Even worse, when waiting for a thread it will cause the other thread to run slower thus requiring an even larger time out. And yes, I've seen this done in production code. I wonder if the reasons for avoiding sleep in this case was the same as then, i.e. MS decided that web scripts shouldn't be able to sleep as they are interactive and might receive a signal.
Admin
The roman numerals sound like what the government contractors use for slots. What it really means is pay grade, i.e., how much salary you can command. In the real world, hiring managers and recruiters invariably use shorthand terms called "Junior", "Midlevel" and "Senior" for how good you actually are. The precise definitions vary, but I use the definitions an old management mentor taught me:
So, if I hire a junior programmer, it does not mean I want a bad one, it means I want someone who can follow precise instructions. Naturally, someone that can handle a higher degree of autonomy will tend to make more money. Having greater technical skill generally means you are more autonomous, but there are plenty of exceptions. Lots of people with mediocre skills can manage themselves, and they are usually more valuable to an employer than an ace who needs to be watched.
Admin
Why the inner for loop ? Works just as good, and holds on a single line.
while(end < DateTime.now) { }
Maybe you worked with the same motorolla compiler we used, at my previous job, that "optimized" every empty loops by jumping over them. I remember seeing code with inlined assembler "NOP" instructions inside empty loops to make them work right...
Admin
Delays don't just hide problems, they create insidious new problems.
I once spent a few weeks helping a developer figure out why our application was running slower on multi-processor machines than it was on single processor machines.
It turned out that there were two threads in the bowels of the application that were designed by a previous developer. The consumer would empty the queue and then go to sleep for 20 milliseconds. The producer would put x objects in the queue and then it too would go to sleep for 20 milliseconds.
On a single processor box, each thread did some work in the 20 millisecond sleep of the other thread.
On a dual processor box, the threads were sleeping more than they were working.