The updated code you posted still doesn't have any form of synchronization. CPU based synchronization ( locks, mutexes etc ) will not help in this case and here is why. Whenever you issue a command to the GPU, it may seem synchronous from an application perspective, but in reality the command may not be executed until several frames later ( drawing blank on link to resources, but there is plenty of documentation online describing this behavior ). With that said, CPU based sync cannot guarantee that the GPU have reached the command in its command stream, you will need GPU sync for that ( GL_NV_fence, GL_ARB_sync, see the man pages ). The only way this may work without synchronization is to unmap the buffer like chm said, or if you are using a GL 4.4 context, mapping the buffer with the persistent bit set. The documentation for glDrawArrays states :
GL_INVALID_OPERATION is generated if a non-zero buffer object name is bound to an enabled array and the buffer object's data store is currently mapped.