Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Post
  • Reply
Chunderstorm
May 9, 2010


legs crossed like a buddhist
smokin' buddha
angry tuna
So, I'm learning C# in class, and in my spare time followed a tutorial to make a text adventure. I tried adding NPC's for the player to talk to, but I keep getting an error when I run my test game. It says 'Object reference not set to instance of an object.'

code:
 npc = new NPC();
            npc.NpcName = "Randy";
            npc.NpcText = "Frigg off, Rick.";
            room.Npcs.Add(npc);
It highlights the last line. It's trying to make a new NPC from this class:

code:
class NPC
    {
        private string npcName;
        private string npcText;

        #region properties

        public string NpcName
        {
            get { return npcName; }
            set { npcName = value; }
        }

        public string NpcText
        {
            get { return npcText; }
            set { npcText = value; }
        }
    }
I don't know how much of the rest of my code is relevant, but everything worked great until I added the NPC's, so I don't know where the problem could be, so I'll just post the rest of the related code.

The following is in my 'Player' class:
code:
 public static void TalkNpc(string npcName)
        {
            Room room = Player.GetCurrentRoom();
            NPC npc = room.GetNPC(npcName);

            if (npc != null)
            {
                TextBuffer.Add(npc.NpcText);
            }
            else
                TextBuffer.Add(npcName + "isn't here.");
        }
And in my 'Room' class:
code:
private List<NPC> npcs;

 public List<NPC> Npcs
        {
            get { return npcs; }
            set { npcs = value; }
        }

public void Describe()
        {
            TextBuffer.Add(this.GetNPCList());
        }

//TextBuffer just outputs text. Probably not relevant, but posting everything having to do with NPC's

public NPC GetNPC(string npcName)
        {
            foreach (NPC npc in this.npcs)
            {
                if (npc.NpcName.ToLower() == npcName.ToLower())
                    return npc;
            }
            return null;
        }

private string GetNPCList()
        {
            string npcString = "";
            string message = "People to talk to:";
            string underline = "";
            underline = underline.PadLeft(message.Length, '-');

            if (this.npcs.Count > 0)
            {
                foreach (NPC npc in this.npcs)
                {
                    npcString += "\n[" + npc.NpcName + "]";
                }
            }
            else
            {
                npcString = "\n<none>";
            }

            return "\n" + message + "\n" + underline + npcString;
        }
Sorry for the wall of text, but I'm clueless.

Adbot
ADBOT LOVES YOU

Drape Culture
Feb 9, 2010

But it was all right, everything was all right, the struggle was finished. He had won the victory over himself. He loved Big Brother.

The End.

HarkToTheLoons posted:

And in my 'Room' class:
code:
private List<NPC> npcs;

 public List<NPC> Npcs
        {
            get { return npcs; }
            set { npcs = value; }
        }


Sorry for the wall of text, but I'm clueless.

Assuming you don't have a constructor for room doing this: npcs is never instantiated, so you can't call on room.Npcs.Add().

Probably should ask in the .NET thread to be sure: http://forums.somethingawful.com/showthread.php?threadid=2262300

Edison was a dick
Apr 3, 2010

direct current :roboluv: only

xPanda posted:

Is there a simple way of passing header include directives to libtool through make? I can't seem to find a way to do so.

I've been mucking around with building and installing compiz on Scientific Linux 6.2, and I've just been trying to build the components without make installing them. Some of the packages depend on other packages and look for them in the --prefix directory tree (in this case /usr), but since I'm just compiling them and not installing them it doesn't find some of the headers it needs. I can see the libtool g++ command and see the -I directives being used, but no matter what I do in the Makefile I can't seem to change what the libtool g++ command includes.

I seem to have worked around the problem with some ugly symlinking, but is there a way of doing this by passing the directory to make?

I haven't played about with libtool much, but autotools writes the Makefiles when you run ./configure. You may be able to set CFLAGS at configure time, which should make those flags be baked into the new Makefiles.
So you could run something like ./configure CFLAGS="-Ifoodir -lfoolib".
It's also possible that configure will have an option to specify the include or library paths for some of its dependencies, ./configure --help may help.
If that doesn't work you can set Make variables on the command line, so instead of running make, run make CFLAGS="-Ifoodir -lfoolib". This may override its internal CFLAGS needed to build though, it may allow you to define EXTRA_CFLAGS, but that depends on the project I think.

In general though, there is an expectation that you are installing software as you build it, so there may be ugly hacks needed the whole way.

Edison was a dick fucked around with this message at 09:58 on Feb 20, 2012

Jam2
Jan 15, 2008

With Energy For Mayhem
I'm trying to find thorough documentation for fscanf. Any leads?

pseudorandom name
May 6, 2007

http://lmgtfy.com/?q=fscanf

Dicky B
Mar 23, 2004

What are you trying to find out that the first few google results don't give you?

pseudorandom name
May 6, 2007

Especially considering the second result is the POSIX spec for the function.

Cantv
Sep 28, 2009
Not sure if this is the right thread for this, but I recently stumbled on to something that was very important to me in highschool. It's a top down shooter that I worked on throughout school that I completely lost touch with. I wouldn't even have the source code, except for some reason I decided to use FutureMe.Org to send it 8 years in to the future to my now self.

I don't want to let my past self down, and I would love to see the game compile and run at least one last time, but it's been so long since I have programmed and the code itself is very shoddy. The key problems I am having is finding a compiler, and making it work with the graphics library it used to call on. It was originally compiled on DJGPP with Allegro as the library, but both have updated enough that I need to make near countless changes to patch my outdated code to the present equivalent.

I would really like to know what kind of options I have for salvaging this.

Here's a link to it: http://pastebin.com/mbSx1mtB


I know that it is very very bad, but it was my first (and last) game (not counting a pong clone and a TERRIBLE blackjack game). Making it a game again would worth a whole lot to me.

Jam2
Jan 15, 2008

With Energy For Mayhem

pseudorandom name posted:

Especially considering the second result is the POSIX spec for the function.

I was trying to find out if fscanf is capable of the kind of character classification that one can corral with ctype.h's islower(...) and tolower(...).

I wanted to throw away tokens that contain non-alpha characters. I ended up looping through a temp char* to discover bad chars and discard the string.

Tonight I have a different question. I am using the CMapPut to store int values.

code:
int n = 1;
CMapPut(myMap, buffer, &n);
Does CMapPut(...) add create a new int on the heap with this value or does it instead point to the int n on the stack? Is this value potentially erroneous once we exit this local stack frame? Should I be initializing the int on the heap with malloc?

Sedro
Dec 31, 2008
cmap.h

quote:

code:
void CMapPut(CMap *cm, const char *key, const void *valueAddr);
The new value is copied from the memory pointed to by valueAddr.

Jam2
Jan 15, 2008

With Energy For Mayhem

Sedro posted:

cmap.h
Thanks. I did not trust my intuition.

Duke of Straylight
Oct 22, 2008

by Y Kant Ozma Post

Cantv posted:

Not sure if this is the right thread for this, but I recently stumbled on to something that was very important to me in highschool. It's a top down shooter that I worked on throughout school that I completely lost touch with. I wouldn't even have the source code, except for some reason I decided to use FutureMe.Org to send it 8 years in to the future to my now self.

I don't want to let my past self down, and I would love to see the game compile and run at least one last time, but it's been so long since I have programmed and the code itself is very shoddy. The key problems I am having is finding a compiler, and making it work with the graphics library it used to call on. It was originally compiled on DJGPP with Allegro as the library, but both have updated enough that I need to make near countless changes to patch my outdated code to the present equivalent.

I would really like to know what kind of options I have for salvaging this.

Here's a link to it: http://pastebin.com/mbSx1mtB


I know that it is very very bad, but it was my first (and last) game (not counting a pong clone and a TERRIBLE blackjack game). Making it a game again would worth a whole lot to me.

Trying to compile this with g++ 4.6.2 and Allegro 4.4.2. I removed the #include <dos.h> and stubbed the PC speaker sound stuff out, I'm on Linux so even if I could try to replace the sound functions with actually working ones they'd be the Linux-specific ioctl solution. Didn't know what the bit of asm in the Mouse function was for so commented it out for now. This got the code to compile, but the static initializations of buffer and blood caused a crash inside Allegro - I moved them past the allegro_init() and set_gfx_mode()s in main() instead. Also I changed the graphics mode to windowed so that it's a little bit easier to deal with. After that the next place where it breaks seems to be not having all those BMPs available, I stopped there because I'm not going to make thirty-five graphics files just to see if I can get this thing to work.

Also, looking a bit further, it seems that what the asm bit in the mouse code did was get the left mouse button's state and put it in mouse_b. It'll be worth trying to figure out what to replace it with once the game runs otherwise.

Oh, and almost forgot, I indented it. Here's what I've got: http://pastebin.ca/2120673 (pastebin.com rejected it for some reason)

Suspicious Dish
Sep 24, 2011

2020 is the year of linux on the desktop, bro
Fun Shoe
Just caught up with the thread. And with all the people complaining about sprintf, I thought I should point out asprintf. Why this isn't in the POSIX spec I have no idea, because it's extremely useful:

code:
int
serialize_json_pair (char **out,
                     char  *key,
                     char  *value)
{
  char *key_escaped, *value_escaped;

  key_escaped = escape_string(key);
  value_escaped = escape_string(value);

  return asprintf(out, "{'%s': '%s'}", key_escaped, value_escaped);
}

{
  char *obj;

  if (serialize_json_pair (&obj, "foo", "bar") >= 0)
    {
      write (socket, obj);
      printf ("DEBUG: writing %s\n", obj);
      free (obj);
    }
  else
    printf ("DEBUG: failed to allocate memory serializing json pair\n");
}
(No, I'm not suggesting this as a real solution, it's just a quick example.)

No, MS doesn't support asprintf, but GNOME has your back: it's in glib, disguised as g_strdup_printf.

Cantv
Sep 28, 2009

Duke of Straylight posted:

Trying to compile this with g++ 4.6.2 and Allegro 4.4.2. I removed the #include <dos.h> and stubbed the PC speaker sound stuff out, I'm on Linux so even if I could try to replace the sound functions with actually working ones they'd be the Linux-specific ioctl solution. Didn't know what the bit of asm in the Mouse function was for so commented it out for now. This got the code to compile, but the static initializations of buffer and blood caused a crash inside Allegro - I moved them past the allegro_init() and set_gfx_mode()s in main() instead. Also I changed the graphics mode to windowed so that it's a little bit easier to deal with. After that the next place where it breaks seems to be not having all those BMPs available, I stopped there because I'm not going to make thirty-five graphics files just to see if I can get this thing to work.

Also, looking a bit further, it seems that what the asm bit in the mouse code did was get the left mouse button's state and put it in mouse_b. It'll be worth trying to figure out what to replace it with once the game runs otherwise.

Oh, and almost forgot, I indented it. Here's what I've got: http://pastebin.ca/2120673 (pastebin.com rejected it for some reason)

Thanks man!

This is awesome news! I had problems getting it to compile because of all the function calls to things no longer supported. I'm going to try downloading Allegro 4.4.2, but I'm a little unsure what compiler to use. Considering getting djgpp back, but I can't quite remember what all the commands I am supposed to enter when I compile. I want to say a "-l -wall" were in there, but it's been a long time. Anyway, I'll update here if it gets closer to working or if I hit another snag.

-e: And Oh god, sorry about the no indentation. I spent more time working on that game than actually learning the things I should have been in comp sci :(

Duke of Straylight
Oct 22, 2008

by Y Kant Ozma Post
Working on code is what you should do to learn compsci :). In case you're worried, all it took to indent it was typing M-x indent-region (in emacs).

If you're compiling with g++, you'll probably need the -lalleg argument to link the Allegro library. Since the program is all in one file, assuming you named it magedot.cpp, compiling it with g++ should only be a matter of running "g++ magedot.cpp -lalleg -Wno-deprecated-declarations -o magedot.exe" and it should create an executable named magedot.exe assuming your compiler and the Allegro library are correctly installed.

If you get errors about not finding allegro.h or -lalleg, you might need to add extra arguments for them: -I/path/to/include/files for the former, -L/path/to/library for the latter. That is a upper-case I and L, followed immediately by the path. And the executable itself won't run without runtime access to the library, it needs to be in PATH or in the directory where you run the game from.

And as for warning options (-Wall is a gcc/g++ option that turns on all common warnings), -Wno-deprecated-declarations is probably essential since textout() and textprintf() are deprecated and this code calls them from a lot of places so they cause a lot of warning spam. Aside that, the code's actually pretty warning-clean, there's just a couple of unused parameters and a single 'if' statement with an empty body.

Jam2
Jan 15, 2008

With Energy For Mayhem
Why is this invalid in C? Are parameters not considered in function signatures?

Only registered members can see post attachments!

feedmegin
Jul 30, 2008

Jam2 posted:

Why is this invalid in C? Are parameters not considered in function signatures?



Correct. What matters is the raw function name. (which is why C compilers, unlike C++, don't have to do name mangling)

floWenoL
Oct 23, 2002

feedmegin posted:

Correct. What matters is the raw function name. (which is why C compilers, unlike C++, don't have to do name mangling)

In other words, C doesn't support function overloading.

csammis
Aug 26, 2003

Mental Institution
Lexical hiding still causes warnings from some C++ compilers by default. g++ - not sure which version - on Solaris has been particularly finicky about this judging from our build output logs.

pseudorandom name
May 6, 2007

floWenoL posted:

In other words, C doesn't support function overloading.

And the contortions C goes through to not support function overloading is embarrassing.

raminasi
Jan 25, 2005

a last drink with no ice

pseudorandom name posted:

And the contortions C goes through to not support function overloading is embarrassing.

What do you mean by this?

pseudorandom name
May 6, 2007

code:
#define pow(x, y) _Generic((x), \
    long double complex: cpowl, \
 
    double complex: _Generic((y), \
    long double complex: cpowl, \
    default: cpow), \
 
    float complex: _Generic((y), \
    long double complex: cpowl, \
    double complex: cpow, \
    default: cpowf), \
 
    long double: _Generic((y), \
    long double complex: cpowl, \
    double complex: cpow, \
    float complex: cpowf, \
    default: powl), \
 
    default: _Generic((y), \
    long double complex: cpowl, \
    double complex: cpow, \
    float complex: cpowf, \
    long double: powl, \
    default: pow), \
 
    float: _Generic((y), \
    long double complex: cpowl, \
    double complex: cpow, \
    float complex: cpowf, \
    long double: powl, \
    float: powf, \
    default: pow) \
    )(x, y)
edit: The best part is that for the decade between the introduction of tgmath.h in C99 and the introduction of _Generic in C11, there was literally no standards-compliant way to implement tgmath.h.

pseudorandom name fucked around with this message at 02:18 on Feb 23, 2012

floWenoL
Oct 23, 2002

pseudorandom name posted:

edit: The best part is that for the decade between the introduction of tgmath.h in C99 and the introduction of _Generic in C11, there was literally no standards-compliant way to implement tgmath.h.

Isn't this more indicative of a need for type parametrization rather than function overloading?

shrughes
Oct 11, 2008

(call/cc call/cc)

Suspicious Dish posted:

Just caught up with the thread. And with all the people complaining about sprintf, I thought I should point out asprintf. Why this isn't in the POSIX spec I have no idea, because it's extremely useful

You can implement it yourself, using va_copy and two calls to vsnprintf.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
I'm a bit fuzzy on how value lifetime works internally when you throw the value. In particular, how is it that you can catch a reference if the reference is to a value that was allocated in a stack frame that's destroyed before the catch block can do anything with it?

Paniolo
Oct 9, 2007

Heads will roll.

OneEightHundred posted:

I'm a bit fuzzy on how value lifetime works internally when you throw the value. In particular, how is it that you can catch a reference if the reference is to a value that was allocated in a stack frame that's destroyed before the catch block can do anything with it?

The exception objects are copied as part of the throwing mechanism which is why you can't throw noncopyable types.

In practice the copy is usually elided though.

edit: I did some poking around Visual C++, the way it handles it is that the value actually exists on the stack at the original call site. A final cleanup handler runs after the final catch block is executed. The copy is elided according to normal NVRO rules, meaning if you've defined a copy constructor it will be elided even if the copy constructor is private. But if you have an implicit copy constructor, no elision occurs, which means if you inherit from a class with non-accessible copy constructors (i.e. boost::noncopyable) you'll get a compile time error.

One last strange thing I found is that if you declare, but don't define, a copy constructor, you'll get a link error, even though it's never actually referenced anywhere in the generated code.

Paniolo fucked around with this message at 08:28 on Feb 24, 2012

Jam2
Jan 15, 2008

With Energy For Mayhem
edit: The CVector has the ability to manage memory allocation for structs.

Jam2 fucked around with this message at 09:57 on Feb 24, 2012

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Paniolo posted:

edit: I did some poking around Visual C++, the way it handles it is that the value actually exists on the stack at the original call site.
I'm assuming by "call site" you mean the catch block?

Paolomania
Apr 26, 2006

OneEightHundred posted:

I'm assuming by "call site" you mean the catch block?

I'm taking it to mean that the data is still just floating there on the now-invalid stack frame of the code block that generated the exception (call-site referring to the instruction that generated the exception). Because you are only popping frames to the point of the catch block, you as the compiler writer can be sure that the exception's frame has not been overwritten. You might need to copy it aside at the point of the handler, because now the handler will potentially be making calls.

Lprsti99
Apr 7, 2011

Everything's coming up explodey!

Pillbug
Ack, losing my mind here. Assignment for my CS250 class, I'm supposed to take input from a file and print it to the console, formatted so that no line is more that a certain number of characters wide. I've got everything working, except that when it reaches the end of a paragraph, it's supposed to skip a line and then start the next. however, mine is skipping the line before the last word of the first paragraph, so instead of it appearing like so:

code:
'Mine is a long and
a sad tale!' said
the Mouse, turning
to Alice, and
sighing.

'It IS a long tail,
certainly,' said
Alice, looking down
with wonder at the
Mouse's tail; 'but
why do you call it
sad?'
it appears so:

code:
'Mine is a long and
a sad tale!' said
the Mouse, turning
to Alice, and

sighing.  'It IS a
long tail,
certainly,' said
Alice, looking down
with wonder at the
Mouse's tail; 'but
why do you call it
sad?' 
My code is as follows:

code:
#include "typeset.h"
#include <string>
#include <sstream>

using namespace std;
bool lineEnd = false;
string getNext(istream& documentIn)
{
string result;

char letter;
while (!documentIn.eof())
{
    letter = documentIn.get();

    if (isspace(letter))
    {
        if (result.length() > 0)
            break;
        else if (letter == '\n')
        {
            lineEnd = true;
            break;
        }
    }


    else
    {
        result += letter;
    }
}
return result;
}

void typeset (int maxWidth, istream& documentIn)
{
string line, word;

while (!documentIn.eof())
{
    if (lineEnd == true)
    {
        cout << "\n";
        lineEnd = false;
    }

    word = getNext(documentIn);

    {
        if (line.length() + word.length() + 1 <= maxWidth)
        {
            if (line.length() > 0) line.append(" ");
            line.append(word);
        }
        else
        {
            cout << line << endl;

            line = word;
        }
    }
}
if (line.length() != 0)
{
cout << line << endl;
}
}
Knowing me, I'm missing something blindingly obvious, but I can't for the life of me figure it out. Can anyone help?

e: Wait, think I see it.

e2: Yep, was obvious, got it.

Lprsti99 fucked around with this message at 20:24 on Feb 24, 2012

Paniolo
Oct 9, 2007

Heads will roll.

Paolomania posted:

I'm taking it to mean that the data is still just floating there on the now-invalid stack frame of the code block that generated the exception (call-site referring to the instruction that generated the exception). Because you are only popping frames to the point of the catch block, you as the compiler writer can be sure that the exception's frame has not been overwritten. You might need to copy it aside at the point of the handler, because now the handler will potentially be making calls.

Yeah this is exactly how it works. I said call site where I meant to say throw site, probably because throwing under VC++ is actually a call to a function called CxxThrowException and that's what I was looking at when I wrote that post.

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!

Paolomania posted:

I'm taking it to mean that the data is still just floating there on the now-invalid stack frame of the code block that generated the exception (call-site referring to the instruction that generated the exception). Because you are only popping frames to the point of the catch block, you as the compiler writer can be sure that the exception's frame has not been overwritten. You might need to copy it aside at the point of the handler, because now the handler will potentially be making calls.
Yeah misread, I thought he meant that the copy is allocated on the stack at the catch site.

Paolomania
Apr 26, 2006

This is what all those foobar!SEHPrologue labels set up, right?

Hughlander
May 11, 2005

Is there anything like this currently in an Open Source library that anyone knows about? At work we have a RAII critical section that grabs a lock in it's constructor and free's it in it's destructor, you make one on the stack and it cleans up itself when it goes out of scope. Frequently though it's used like this:

code:
    ScopedCritSection(m_TheCritSection)
    if(m_pResource)
    {
        m_pResource->UseResource();
    }
Because other threads could be cleaning up / shutting down the app you need to check for NULL and aquire the lock as well. I thought about making a class that was a Weak Ref holder to the resource, but also a ref counted smart pointer to the critical section lock. So instead you'd have something like:

code:
    {
       ResourceHolder* pResource = GetResource(); // Call to GetResource blocks until  m_TheCritSection can be locked
        if(pResource) // pResource has a weak ref to the resource so can still be NULL
        {
            pResource->UseResource();
        }
    } // pResource out of scope, ref count of the smart pointer to m_TheCritSection decremented and lock released if it reached 0

    g_pGlobalResource = GetResource(); // Resource attached to a global won't be released until the global assigned to NULL / another value.
Anything like this exists? Or why is it a horrible horrible idea?

floWenoL
Oct 23, 2002

Hughlander posted:


code:
    {
       ResourceHolder* pResource = GetResource(); // Call to GetResource blocks until  m_TheCritSection can be locked
        if(pResource) // pResource has a weak ref to the resource so can still be NULL
        {
            pResource->UseResource();
        }
    } // pResource out of scope, ref count of the smart pointer to m_TheCritSection decremented and lock released if it reached 0

This code doesn't make sense. pResource (a pointer) goes out of scope, but how can you possibly hook into that to (say) decrement a ref-count?

You probably want something like:

code:
  {
    ResourceHandle h(some_shared_resource);
    if (h.get()) {
      h.get()->UseResource();
    }
  }
But that's just your original code. So what are you trying to do?

I assume you have a good reason for doing concurrency with shared data instead of, say, a message loop to control access to the resource.

shrughes
Oct 11, 2008

(call/cc call/cc)
More like

code:
  {
    ResourceHandle h(some_shared_resource);
    if (h.get()) {
      h->UseResource();
    }
  }
Edit: But no. This is bad in general. A ResourceHandle nonchalantly and secretly acquiring some lock? Locking absolutely has to be explicit and done with care.

Edit: (So name it a ResourceLock.)

Edit: Also, as floW said or implied, there are better ways to do this, and deal with shutdown, in general. It seems like you'll find it easy to have bugs on shutdown, doing things this way.

shrughes fucked around with this message at 00:27 on Feb 25, 2012

Hughlander
May 11, 2005

floWenoL posted:

This code doesn't make sense. pResource (a pointer) goes out of scope, but how can you possibly hook into that to (say) decrement a ref-count?

You probably want something like:

code:
  {
    ResourceHandle h(some_shared_resource);
    if (h.get()) {
      h.get()->UseResource();
    }
  }
But that's just your original code. So what are you trying to do?

I assume you have a good reason for doing concurrency with shared data instead of, say, a message loop to control access to the resource.

I'll write up some actual code with what I was thinking.
My thought basically was that the ResourceHolder has two member variables, a pointer to the resource, and a smart pointer to a critical section class. The destructor for ResourceHolder would decrement the smart pointer allowing it to unlock. I would't want what's in your example though as between the if and the UseResource the shared resource could be deleted.

shurghes posted:

Edit: But no. This is bad in general. A ResourceHandle nonchalantly and secretly acquiring some lock? Locking absolutely has to be explicit and done with care.

Not sure which is worse, secretly acquiring some lock, or spending tons of hours tracking down cases where coders don't feel like they need to acquire the lock and testing for the existence of the object is sufficient. (Which is what happened and led to a crash in the live environment that never came up in 3 years of development.)

As I said it was just something I was thinking about to see if others have done it and bounce it off other people as to why it may be a bad idea.

floWenoL
Oct 23, 2002

Hughlander posted:

Not sure which is worse, secretly acquiring some lock, or spending tons of hours tracking down cases where coders don't feel like they need to acquire the lock and testing for the existence of the object is sufficient. (Which is what happened and led to a crash in the live environment that never came up in 3 years of development.)

It sounds like the problem is needing a lock in the first place.

P.S.:
Your avatar is making me confuse you with CptMath.

Jabor
Jul 16, 2010

#1 Loser at SpaceChem
There is literally no way to make concurrency idiot-proof (at least, not without placing big restrictions on it). The correct solution is to not have idiots writing concurrent code.

Or if you can't do that for whatever reason, have some sane development practices so that their code is vetted by a non-idiot before it actually gets used.

Adbot
ADBOT LOVES YOU

OneEightHundred
Feb 28, 2008

Soon, we will be unstoppable!
Shutdowns/cleanup should be waiting until all work threads have stopped, if you can't do that then at least create a mutex that prevents resource destruction and resource acquisition for a thread from happening at the same time.

If you insist on flagging resources for deletion while threads are working on them, use a refcount (and use atomic increment/decrement!) and decref the resource when it leaves the main resource pool so a work thread will nukes it when it finishes.

  • 1
  • 2
  • 3
  • 4
  • 5
  • Post
  • Reply