1 /* QuesoGLC
2  * A free implementation of the OpenGL Character Renderer (GLC)
3  * Copyright (c) 2002, 2004-2007, Bertrand Coconnier
4  *
5  *  This library is free software; you can redistribute it and/or
6  *  modify it under the terms of the GNU Lesser General Public
7  *  License as published by the Free Software Foundation; either
8  *  version 2.1 of the License, or (at your option) any later version.
9  *
10  *  This library is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  *  Lesser General Public License for more details.
14  *
15  *  You should have received a copy of the GNU Lesser General Public
16  *  License along with this library; if not, write to the Free Software
17  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
18  */
19 /* $Id: test3.c 679 2007-12-20 21:42:13Z bcoconni $ */
20 
21 /** \file
22  * The purpose of this test is to check that a context can be bound to only
23  * one thread at a time. This test checks that if a context is current to
24  * a thread other than the issuing thread then a GLC_STATE_ERROR is raised.
25  * Pending deletion of contexts is also tested.
26  */
27 
28 #include "GL/glc.h"
29 #include <pthread.h>
30 #include <stdio.h>
31 #if defined __APPLE__ && defined __MACH__
32 #include <GLUT/glut.h>
33 #else
34 #include <GL/glut.h>
35 #endif
36 
37 GLint ctx;
38 int magic = 0xdeadbeef;
39 
da_thread(void * arg)40 void* da_thread(void *arg)
41 {
42   GLCenum err;
43 
44   glutCreateWindow("test3.1");
45 
46   glcContext(ctx);
47   err = glcGetError();
48   if (err != GLC_STATE_ERROR) {
49     printf("Thread 2 : Unexpected error : 0x%X\n", (int)err);
50     return &magic;
51   }
52 
53   /* Ask GLC to delete this context as soon as it is not current any thread */
54   glcDeleteContext(ctx);
55   err = glcGetError();
56   if (err) {
57     printf("Thread 2 : Unexpected error : 0x%X\n", (int)err);
58     return &magic;
59   }
60   /* Check that the context has not been deleted yet. */
61   if (!glcIsContext(ctx)) {
62     printf("Thread 2 : Unexpected deletion of context %d\n", (int)ctx);
63     return &magic;
64   }
65 
66   return NULL;
67 }
68 
main(int argc,char ** argv)69 int main(int argc, char **argv)
70 {
71   pthread_t thread;
72   GLCenum err;
73   void *return_value = NULL;
74   GLint ctx2;
75 
76   /* Needed to initialize an OpenGL context */
77   glutInit(&argc, argv);
78   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB);
79   glutCreateWindow("test3");
80 
81   ctx2 = glcGenContext();
82   ctx = glcGenContext();
83   glcContext(ctx);
84   err = glcGetError();
85   if (err) {
86     printf("Main Thread : Unexpected error : 0x%X\n", (int)err);
87     return -1;
88   }
89 
90   if (pthread_create(&thread, NULL, da_thread, NULL)) {
91     printf("Main Thread : Failed to create pthread\n");
92     return -1;
93   }
94 
95   if (pthread_join(thread, &return_value)) {
96     printf("Main Thread : Failed to join Thread 2\n");
97     return -1;
98   }
99 
100   if (return_value) {
101     printf("Main Thread : An error occured in Thread 2\n");
102     return -1;
103   }
104 
105   /* Check that although the thread has requested a deletion of the context,
106    * the context 'ctx' still exists.
107    */
108   if (!glcIsContext(ctx)) {
109     printf("Main Thread : Unexpected deletion of context 'ctx'\n");
110     return -1;
111   }
112 
113   /* Change the current context. The pending deletion should be executed
114    * at this step.
115    */
116   glcContext(ctx2);
117   /* Verify that the context has been deleted */
118   if (glcIsContext(ctx)) {
119     printf("Main Thread : Pending deletion of context 'ctx' has not been executed\n");
120     return -1;
121   }
122 
123   /* Same as above (pending deletion of a context) but a little different :
124    * - The deletion is now requested in the thread that owns the context
125    * - glcContext(0) is called which means that the current context will be
126    *   released and no other context will be made current (hence a different
127    *   branch of code will be executed in glcContext().
128    */
129   glcDeleteContext(ctx2);
130   err = glcGetError();
131   if (err) {
132     printf("Main Thread : Unexpected GLC error 0x%x\n", (int)err);
133     return -1;
134   }
135 
136   /* Release the current context */
137   glcContext(0);
138   /* Check that 'ctx2' has been deleted */
139   if (glcIsContext(ctx2)) {
140     printf("Main Thread : Pending deletion of context 'ctx2' has not been executed\n");
141     return -1;
142   }
143 
144   printf("Test successful!\n");
145   return 0;
146 }
147