Concurrent list modification error.

About Monkey 2 Forums Monkey 2 Development Concurrent list modification error.

This topic contains 15 replies, has 7 voices, and was last updated by  nerobot 2 years, 4 months ago.

Viewing 15 posts - 1 through 15 (of 16 total)
  • Author
    Posts
  • #4722

    Richard Betson
    Participant

    Howdy,

    I get a concurrent list modification error if I do something like this.

    Is this a bug or does Monkey 2 not support this as Monkey X did?

    #4726

    peterigz
    Participant

    You’ll need to do something along these lines:

    #4732

    Richard Betson
    Participant

    Well. I’ll give that a try…. but.

    This issue is particularly confusing when converting Monkey X code. When Monkey 2 compiles code it will error on list.Remove() with no line reference in debug and just crashes the compiled application in release. So a user who does not know this is an issue is in some cases going to have a tough time figuring out what is going wrong. Believe me, I had a tough time narrowing the issue down with my large code base.

    Anyway for continuities sake it might be a good idea to have Monkey 2 work as Monkey X did in this case.

    #4733

    Mark Sibly
    Keymaster

    I wont be changing this – there’s just no easy way to guarantee you’re not completely messing up a list by removing stuff will you’re iterating through it, and I’m sure there’s a fair few ‘sneaky’ bugs out there due to this.

    It showed up fine in the debugger for me, I just had to click on the first non-module function in the debug view.

    Here’s a super-duper fast way to remove stuff while iterating through a stack:

    #4735

    Jesse
    Participant

    @Richard
    Your code on the first post works fine as is. I tried it and it does not give any errors compiling it with the latest MX2. The error must be somewhere else in your code.

    #4736

    Mark Sibly
    Keymaster

    >Your code on the first post works fine as is

    The code as posted doesn’t compile, and ‘fixing’ it still leaves you with an empty list! I had to add an item to break it.

    It should also be mentioned that peterigz’s solution is faster – List.Remove() needs to find the item’s node using a linear search, while it.Remove() can just remove the node directly.

    #4737

    Jesse
    Participant

    correction I did get the error by adding an item to the list:

    [/crayon]
    #4739

    Jesse
    Participant

    I guess we are crossing posts. Hahahah!

    I usually only do it like this:

    [/crayon]

    This should be a bit faster. I suspect.

    #4742

    Mark Sibly
    Keymaster

    Does that even work? Isn’t link.Succ null after the Remove()?

    Weirdly, I have grown to really dislike  ‘stunt’ list processing!

    And of course, List.Clear() is fastest…

    #4743

    Jesse
    Participant

    > Does that even work? Isn’t link.Succ null after the Remove()?

    You should know. you wrote it! :).
    but yes it works.

    >And of course, List.Clear() is fastest…
    yes its faster. but for my usage which is not as simple as that, mine is a better option.

    [/crayon]

    I don’t see that as much of a stunt as its all part of List’s public functionality.

    #4755

    Richard Betson
    Participant

    I’ll give the above samples a try. I’m cool with the fact that this this is how it has to be. I’ll adapt. 😉

    Thanks!

    #4757

    Mark Sibly
    Keymaster

    > I’ll give the above samples a try.

    The above code for iterating through a container is a bit wrong – here’a another example that also removes items as it goes:

     

    Note that you can replace List with Stack or Deque and it will look/work the same way.

    I don’t see that as much of a stunt as its all part of List’s public functionality.

    But it does depend on undocumented behaviour, eg: it assumes a node can still safely be used after it’s been removed from a list, and also that the ‘head’ node has a null value so you know when you’ve reached the end of list. This is what I mean by ‘stunt’ programming – relying on undocumented implementation details. There is a correct (ie: documented) way to do what you want (see above) so IMO it makes sense to use it.

    In fact, your code *does* break here on the latest version, as I cleaned up node remove so that the node could still be inserted elsewhere safely, but I think I’ll give up on try to make a ‘clean’ list class and just concentrate on trying to duplicate bmx’s/monkey1’s quirks instead!

    Think it’s also time to add RemoveIf() too!

    #4760

    skn3
    Participant

    What if Stack (and others) had a new method for running an operation for each item in series.

    For example:

    This could be used for a lot more then just removing!

     

    Also clearly this is not the most efficient way to iterate and do stuff, but it works.

    In these example the Do creates a list of items at the time of calling, so this is then safe to iterate over. It generates junk, but this could be optimised. Or a safe/unsafe flag could be specified, causing the loop to iterate directly, or create the array first with safe mode. e.g.

     

    Another example:

    #4771

    Richard Betson
    Participant

    but I think I’ll give up on try to make a ‘clean’ list class and just concentrate on trying to duplicate bmx’s/monkey1’s quirks instead!

    Applause. 🙂 I look at this issue as how best can MX2 provide continuity and how can MX2 provide intensives for BlitzMax users to climb on-board. One way is by including often used legacy commands and syntax where possible. I’m not selling the idea of backpedaling but making a case for simpler conversions of legacy code.

    I’m in the middle of solidifying my converted code base, but when that is done I intend to explore Stac’s and determine where best to use them and what limitations they hold. I like List’s and when used properly it is a nice feature to have. After converting a ton of legacy code Monkey 2 has proven to be friendly to the process and support of List’s and some of the past quirks is a good Idea to further smoother legacy conversions.

    #5486

    MikeHart
    Participant

    How would someone implement an extention to a container while iterating through the same? Simple .AddLast or .Push/.Add?

Viewing 15 posts - 1 through 15 (of 16 total)

You must be logged in to reply to this topic.