YaGL: Fixed for khronos GLESv2 test: programs and shaders must be in same namespace
authorStanislav Vorobiov <s.vorobiov@samsung.com>
Tue, 6 Nov 2012 17:49:55 +0000 (21:49 +0400)
committerEvgeny Voevodin <e.voevodin@samsung.com>
Mon, 26 Nov 2012 09:25:31 +0000 (13:25 +0400)
YaGL: Fixed for khronos GLESv2 test: n < 0 checks added to glGenXXX
YaGL: Fixed for khronos GLESv2 test: namespace local name generation must take user binded names into account

hw/yagl_apis/gles/yagl_host_gles_calls.c
hw/yagl_apis/gles2/yagl_gles2_program.c
hw/yagl_apis/gles2/yagl_gles2_program.h
hw/yagl_apis/gles2/yagl_gles2_shader.c
hw/yagl_apis/gles2/yagl_gles2_shader.h
hw/yagl_apis/gles2/yagl_host_gles2_calls.c
hw/yagl_namespace.c
hw/yagl_sharegroup.c
hw/yagl_sharegroup.h

index d0fba5afd7312fe39e641fd40179ee7d26683e87..86927e352ab3c6905b23d4ab9be368def472495a 100644 (file)
@@ -853,6 +853,11 @@ bool yagl_host_glGenBuffers(GLsizei n,
 
     YAGL_GET_CTX(glGenBuffers);
 
+    if (n < 0) {
+        YAGL_SET_ERR(GL_INVALID_VALUE);
+        goto out;
+    }
+
     if (!yagl_mem_prepare(ts->mt1, buffers_, n * sizeof(*buffer_names))) {
         res = false;
         goto out;
@@ -900,6 +905,11 @@ bool yagl_host_glGenTextures(GLsizei n,
 
     YAGL_GET_CTX(glGenTextures);
 
+    if (n < 0) {
+        YAGL_SET_ERR(GL_INVALID_VALUE);
+        goto out;
+    }
+
     if (!yagl_mem_prepare(ts->mt1, textures_, n * sizeof(*texture_names))) {
         res = false;
         goto out;
index ef10d277db905d62f490dd9bcbd0b0c56ea90ada..6537e296e43b3d6330bc00710fedac3d0540faae 100644 (file)
@@ -30,6 +30,7 @@ struct yagl_gles2_program
 
     yagl_object_init(&program->base, &yagl_gles2_program_destroy);
 
+    program->is_shader = false;
     program->driver_ps = driver_ps;
     program->global_name = global_name;
 
index d4840e39536c8d1240acff1e2b2aabf04adf2047..ccaca37a08eb4f1f25eed6f6988d5d4f535b9c88 100644 (file)
@@ -4,15 +4,22 @@
 #include "yagl_types.h"
 #include "yagl_object.h"
 
-#define YAGL_NS_PROGRAM 5
-
 struct yagl_gles2_driver_ps;
 struct yagl_gles2_shader;
 
 struct yagl_gles2_program
 {
+    /*
+     * These members must be exactly as in yagl_gles2_shader
+     * @{
+     */
     struct yagl_object base;
 
+    bool is_shader;
+    /*
+     * @}
+     */
+
     struct yagl_gles2_driver_ps *driver_ps;
 
     yagl_object_name global_name;
index 87424d7fbaeb31775982d23413380e05a296599b..808be060b1a8981e27ff58c9148f0f3cc8454968 100644 (file)
@@ -39,6 +39,7 @@ struct yagl_gles2_shader
 
     yagl_object_init(&shader->base, &yagl_gles2_shader_destroy);
 
+    shader->is_shader = true;
     shader->driver_ps = driver_ps;
     shader->global_name = global_name;
     shader->type = type;
index 10d1da615ff77320461451f6af94a58ac679d2ab..32a2ff7edc6fd3017437cb94996804d6c0641237 100644 (file)
@@ -4,14 +4,27 @@
 #include "yagl_types.h"
 #include "yagl_object.h"
 
-#define YAGL_NS_SHADER 4
+/*
+ * Programs and shaders share the same namespace,
+ * pretty clumsy!
+ */
+#define YAGL_NS_SHADER_PROGRAM 4
 
 struct yagl_gles2_driver_ps;
 
 struct yagl_gles2_shader
 {
+    /*
+     * These members must be exactly as in yagl_gles2_program
+     * @{
+     */
     struct yagl_object base;
 
+    bool is_shader;
+    /*
+     * @}
+     */
+
     struct yagl_gles2_driver_ps *driver_ps;
 
     yagl_object_name global_name;
index 0115cc10484155f72d3f31f68cc30e564a7d5827..240c10cef9ede6b4375f65a573a10401adf2d120 100644 (file)
@@ -219,21 +219,31 @@ bool yagl_host_glAttachShader(GLuint program,
     YAGL_GET_CTX(glAttachShader);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_SHADER, shader);
+        YAGL_NS_SHADER_PROGRAM, shader);
 
     if (!shader_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (!shader_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (!yagl_gles2_program_attach_shader(program_obj, shader_obj, shader)) {
         YAGL_SET_ERR(GL_INVALID_OPERATION);
         goto out;
@@ -257,13 +267,18 @@ bool yagl_host_glBindAttribLocation(GLuint program,
     YAGL_GET_CTX(glBindAttribLocation);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (name_) {
         name = yagl_mem_get_string(gles2_api_ts->ts, name_);
         if (!name) {
@@ -431,13 +446,18 @@ bool yagl_host_glCompileShader(GLuint shader)
     YAGL_GET_CTX(glCompileShader);
 
     shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_SHADER, shader);
+        YAGL_NS_SHADER_PROGRAM, shader);
 
     if (!shader_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (!shader_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     yagl_gles2_shader_compile(shader_obj);
 
 out:
@@ -460,7 +480,7 @@ bool yagl_host_glCreateProgram(GLuint* retval)
         goto out;
     }
 
-    *retval = yagl_sharegroup_add(ctx->sg, YAGL_NS_PROGRAM, &program->base);
+    *retval = yagl_sharegroup_add(ctx->sg, YAGL_NS_SHADER_PROGRAM, &program->base);
 
 out:
     yagl_gles2_program_release(program);
@@ -484,7 +504,7 @@ bool yagl_host_glCreateShader(GLuint* retval,
         goto out;
     }
 
-    *retval = yagl_sharegroup_add(ctx->sg, YAGL_NS_SHADER, &shader->base);
+    *retval = yagl_sharegroup_add(ctx->sg, YAGL_NS_SHADER_PROGRAM, &shader->base);
 
 out:
     yagl_gles2_shader_release(shader);
@@ -534,13 +554,35 @@ out:
 
 bool yagl_host_glDeleteProgram(GLuint program)
 {
+    struct yagl_gles2_program *program_obj = NULL;
+
     YAGL_GET_CTX(glDeleteProgram);
 
+    if (program == 0) {
+        goto out;
+    }
+
+    program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
+        YAGL_NS_SHADER_PROGRAM, program);
+
+    if (!program_obj) {
+        YAGL_SET_ERR(GL_INVALID_VALUE);
+        goto out;
+    }
+
+    if (program_obj->is_shader) {
+        goto out;
+    }
+
     yagl_gles2_context_unuse_program(ctx, program);
 
-    yagl_sharegroup_remove(ctx->sg,
-                           YAGL_NS_PROGRAM,
-                           program);
+    yagl_sharegroup_remove_check(ctx->sg,
+                                 YAGL_NS_SHADER_PROGRAM,
+                                 program,
+                                 &program_obj->base);
+
+out:
+    yagl_gles2_program_release(program_obj);
 
     return true;
 }
@@ -587,11 +629,33 @@ out:
 
 bool yagl_host_glDeleteShader(GLuint shader)
 {
+    struct yagl_gles2_shader *shader_obj = NULL;
+
     YAGL_GET_CTX(glDeleteShader);
 
-    yagl_sharegroup_remove(ctx->sg,
-                           YAGL_NS_SHADER,
-                           shader);
+    if (shader == 0) {
+        goto out;
+    }
+
+    shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
+        YAGL_NS_SHADER_PROGRAM, shader);
+
+    if (!shader_obj) {
+        YAGL_SET_ERR(GL_INVALID_VALUE);
+        goto out;
+    }
+
+    if (!shader_obj->is_shader) {
+        goto out;
+    }
+
+    yagl_sharegroup_remove_check(ctx->sg,
+                                 YAGL_NS_SHADER_PROGRAM,
+                                 shader,
+                                 &shader_obj->base);
+
+out:
+    yagl_gles2_shader_release(shader_obj);
 
     return true;
 }
@@ -605,21 +669,31 @@ bool yagl_host_glDetachShader(GLuint program,
     YAGL_GET_CTX(glDetachShader);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_SHADER, shader);
+        YAGL_NS_SHADER_PROGRAM, shader);
 
     if (!shader_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (!shader_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (!yagl_gles2_program_detach_shader(program_obj, shader_obj, shader)) {
         YAGL_SET_ERR(GL_INVALID_OPERATION);
         goto out;
@@ -781,6 +855,11 @@ bool yagl_host_glGenFramebuffers(GLsizei n,
 
     YAGL_GET_CTX(glGenFramebuffers);
 
+    if (n < 0) {
+        YAGL_SET_ERR(GL_INVALID_VALUE);
+        goto out;
+    }
+
     if (!yagl_mem_prepare(gles2_api_ts->ts->mt1, framebuffers_, n * sizeof(*framebuffer_names))) {
         res = false;
         goto out;
@@ -828,6 +907,11 @@ bool yagl_host_glGenRenderbuffers(GLsizei n,
 
     YAGL_GET_CTX(glGenRenderbuffers);
 
+    if (n < 0) {
+        YAGL_SET_ERR(GL_INVALID_VALUE);
+        goto out;
+    }
+
     if (!yagl_mem_prepare(gles2_api_ts->ts->mt1, renderbuffers_, n * sizeof(*renderbuffer_names))) {
         res = false;
         goto out;
@@ -883,13 +967,18 @@ bool yagl_host_glGetActiveAttrib(GLuint program,
     YAGL_GET_CTX(glGetActiveAttrib);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (bufsize > 0) {
         name = yagl_gles_context_malloc(&ctx->base, bufsize);
     }
@@ -953,13 +1042,18 @@ bool yagl_host_glGetActiveUniform(GLuint program,
     YAGL_GET_CTX(glGetActiveUniform);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (bufsize > 0) {
         name = yagl_gles_context_malloc(&ctx->base, bufsize);
     }
@@ -1018,13 +1112,18 @@ bool yagl_host_glGetAttachedShaders(GLuint program,
     YAGL_GET_CTX(glGetAttachedShaders);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (maxcount < 0) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
@@ -1082,13 +1181,18 @@ bool yagl_host_glGetAttribLocation(int* retval,
     *retval = 0;
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (name_) {
         name = yagl_mem_get_string(gles2_api_ts->ts, name_);
         if (!name) {
@@ -1164,13 +1268,18 @@ bool yagl_host_glGetProgramiv(GLuint program,
     }
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (params_) {
         if (!yagl_mem_get_GLint(gles2_api_ts->ts, params_, &params)) {
             res = false;
@@ -1203,13 +1312,18 @@ bool yagl_host_glGetProgramInfoLog(GLuint program,
     YAGL_GET_CTX(glGetProgramInfoLog);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (bufsize < 0) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
@@ -1281,13 +1395,18 @@ bool yagl_host_glGetShaderiv(GLuint shader,
     }
 
     shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_SHADER, shader);
+        YAGL_NS_SHADER_PROGRAM, shader);
 
     if (!shader_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (!shader_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (params_) {
         if (!yagl_mem_get_GLint(gles2_api_ts->ts, params_, &params)) {
             res = false;
@@ -1320,13 +1439,18 @@ bool yagl_host_glGetShaderInfoLog(GLuint shader,
     YAGL_GET_CTX(glGetShaderInfoLog);
 
     shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_SHADER, shader);
+        YAGL_NS_SHADER_PROGRAM, shader);
 
     if (!shader_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (!shader_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (bufsize < 0) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
@@ -1418,13 +1542,18 @@ bool yagl_host_glGetShaderSource(GLuint shader,
     YAGL_GET_CTX(glGetShaderSource);
 
     shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_SHADER, shader);
+        YAGL_NS_SHADER_PROGRAM, shader);
 
     if (!shader_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (!shader_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (bufsize < 0) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
@@ -1491,13 +1620,18 @@ bool yagl_host_glGetUniformLocation(int* retval,
     *retval = 0;
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     if (name_) {
         name = yagl_mem_get_string(gles2_api_ts->ts, name_);
         if (!name) {
@@ -1670,10 +1804,10 @@ bool yagl_host_glIsProgram(GLboolean* retval,
     *retval = GL_FALSE;
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (program_obj) {
-        *retval = GL_TRUE;
+        *retval = program_obj->is_shader ? GL_FALSE : GL_TRUE;
     }
 
     yagl_gles2_program_release(program_obj);
@@ -1712,10 +1846,10 @@ bool yagl_host_glIsShader(GLboolean* retval,
     *retval = GL_FALSE;
 
     shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_SHADER, shader);
+        YAGL_NS_SHADER_PROGRAM, shader);
 
     if (shader_obj) {
-        *retval = GL_TRUE;
+        *retval = shader_obj->is_shader ? GL_TRUE : GL_FALSE;
     }
 
     yagl_gles2_shader_release(shader_obj);
@@ -1730,13 +1864,18 @@ bool yagl_host_glLinkProgram(GLuint program)
     YAGL_GET_CTX(glLinkProgram);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     yagl_gles2_program_link(program_obj);
 
 out:
@@ -1803,13 +1942,18 @@ bool yagl_host_glShaderSource(GLuint shader,
     }
 
     shader_obj = (struct yagl_gles2_shader*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_SHADER, shader);
+        YAGL_NS_SHADER_PROGRAM, shader);
 
     if (!shader_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (!shader_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     string_ptrs = g_malloc(count * sizeof(*string_ptrs));
     if (!yagl_mem_get(gles2_api_ts->ts, string_, count * sizeof(*string_ptrs), string_ptrs)) {
         res = false;
@@ -2293,12 +2437,17 @@ bool yagl_host_glUseProgram(GLuint program)
 
     if (program != 0) {
         program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-            YAGL_NS_PROGRAM, program);
+            YAGL_NS_SHADER_PROGRAM, program);
 
         if (!program_obj) {
             YAGL_SET_ERR(GL_INVALID_VALUE);
             goto out;
         }
+
+        if (program_obj->is_shader) {
+            YAGL_SET_ERR(GL_INVALID_OPERATION);
+            goto out;
+        }
     }
 
     yagl_gles2_context_use_program(ctx, program);
@@ -2319,13 +2468,18 @@ bool yagl_host_glValidateProgram(GLuint program)
     YAGL_GET_CTX(glValidateProgram);
 
     program_obj = (struct yagl_gles2_program*)yagl_sharegroup_acquire_object(ctx->sg,
-        YAGL_NS_PROGRAM, program);
+        YAGL_NS_SHADER_PROGRAM, program);
 
     if (!program_obj) {
         YAGL_SET_ERR(GL_INVALID_VALUE);
         goto out;
     }
 
+    if (program_obj->is_shader) {
+        YAGL_SET_ERR(GL_INVALID_OPERATION);
+        goto out;
+    }
+
     yagl_gles2_program_validate(program_obj);
 
 out:
index dc83dba941d61bba5ac9b77adf122c54cdcbcfb7..37373b7143dc57af6fb5361d164974cdb015b5cc 100644 (file)
@@ -77,20 +77,25 @@ yagl_object_name yagl_namespace_add(struct yagl_namespace *ns,
     struct yagl_namespace_entry *item =
         g_malloc0(sizeof(struct yagl_namespace_entry));
 
-    if (!ns->next_local_name) {
-        /*
-         * 0 names are invalid.
-         */
-
-        ++ns->next_local_name;
-    }
+    yagl_object_acquire(obj);
 
-    item->local_name = ns->next_local_name++;
     item->obj = obj;
 
-    yagl_object_acquire(obj);
+    do {
+        if (!ns->next_local_name) {
+            /*
+             * 0 names are invalid.
+             */
+
+            ++ns->next_local_name;
+        }
+
+        item->local_name = ns->next_local_name++;
 
-    yagl_avl_assert_insert(ns->entries, item);
+        /*
+         * Find a free local name.
+         */
+    } while (yagl_avl_insert(ns->entries, item));
 
     return item->local_name;
 }
index 0b1fce30111adf1d9fc43a0b0ff0be5928b185c0..88ff7ddf68e58b839d05597c47950b537c2b2d21 100644 (file)
@@ -158,6 +158,33 @@ void yagl_sharegroup_remove(struct yagl_sharegroup *sg,
     yagl_sharegroup_release_objects(&tmp);
 }
 
+void yagl_sharegroup_remove_check(struct yagl_sharegroup *sg,
+                                  int ns,
+                                  yagl_object_name local_name,
+                                  struct yagl_object *obj)
+{
+    struct yagl_object_list tmp;
+    struct yagl_object *actual_obj;
+
+    QLIST_INIT(&tmp);
+
+    qemu_mutex_lock(&sg->mutex);
+
+    yagl_sharegroup_reap_list_move(sg, &tmp);
+
+    actual_obj = yagl_namespace_acquire(&sg->namespaces[ns], local_name);
+
+    if (actual_obj == obj) {
+        yagl_namespace_remove(&sg->namespaces[ns], local_name);
+    }
+
+    yagl_object_release(actual_obj);
+
+    qemu_mutex_unlock(&sg->mutex);
+
+    yagl_sharegroup_release_objects(&tmp);
+}
+
 struct yagl_object *yagl_sharegroup_acquire_object(struct yagl_sharegroup *sg,
                                                    int ns,
                                                    yagl_object_name local_name)
index 170c3cf13d5bd79907d6abd715f42fb55ffd54e9..b06ee87292a758b4bb6e3e7488e49c451f796895 100644 (file)
@@ -7,7 +7,7 @@
 #include "qemu-thread.h"
 #include "qemu-queue.h"
 
-#define YAGL_NUM_NAMESPACES 6
+#define YAGL_NUM_NAMESPACES 5
 
 struct yagl_sharegroup_reap_entry;
 
@@ -97,6 +97,15 @@ void yagl_sharegroup_remove(struct yagl_sharegroup *sg,
                             int ns,
                             yagl_object_name local_name);
 
+/*
+ * Same as 'yagl_sharegroup_remove', but removes only if and object
+ * behind 'local_name' is 'obj'
+ */
+void yagl_sharegroup_remove_check(struct yagl_sharegroup *sg,
+                                  int ns,
+                                  yagl_object_name local_name,
+                                  struct yagl_object *obj);
+
 /*
  * Acquires an object by its local name. Be sure to release the object when
  * you're done.